diff --git a/DEPS b/DEPS
index b7ac0c8..b7c845d 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,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': '964dec3948721808491b21b4ff4ff41a466443ec',
+  'skia_revision': '6f67fc29eddfb6f415f7e6a86197db5d8c8539ed',
   # 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': '9b59b4b58270e9f5009b124e450cca2bd95ce6c7',
+  'v8_revision': 'e00a560bfeb6217733488898d5b2e7b8e44e5c58',
   # 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.
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '98909bf9f458614abc1bb7f4df34a319a1d5ce3f',
+  'pdfium_revision': '0370d6b8aab1b7880dd2727e7d9aed04cc358360',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'e1e778d78de1742159a4247af6789b371e3aae59',
+  'catapult_revision': '50b8d5f68b27f47e657aa871cac6f8fb6a56d96c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
diff --git a/WATCHLISTS b/WATCHLISTS
index a6cd5cd..dbfda0f 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -751,7 +751,9 @@
           'chrome/browser/ui/webui/options/',
     },
     'origin_trials': {
-      'filepath': 'origin_trials',
+      'filepath': 'origin_trials'\
+                  '|OriginTrial'\
+                  '|ConditionalFeature',
     },
     'ozone': {
       'filepath': 'ui/ozone/|'\
@@ -1935,7 +1937,8 @@
                           'sbc@chromium.org'],
     'navigation': ['creis+watch@chromium.org',
                    'nasko+codewatch@chromium.org'],
-    'net': ['cbentzel+watch@chromium.org'],
+    'net': ['cbentzel+watch@chromium.org',
+            'net-reviews@chromium.org'],
     'net_error_list': ['mmenke@chromium.org'],
     'net_log': ['eroman@chromium.org',
                 'mmenke@chromium.org'],
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index 056656de..cc114f8f 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -718,7 +718,6 @@
     "java/src/org/chromium/android_webview/crash/MinidumpUploaderImpl.java",
     "java/src/org/chromium/android_webview/crash/MinidumpUploader.java",
     "java/src/org/chromium/android_webview/crash/MinidumpUploadJobService.java",
-    "java/src/org/chromium/android_webview/crash/SynchronizedWebViewCommandLine.java",
   ]
   deps = [
     "//base:base_java",
diff --git a/android_webview/browser/aw_safe_browsing_resource_throttle.cc b/android_webview/browser/aw_safe_browsing_resource_throttle.cc
index 507a0a5..b77c97d 100644
--- a/android_webview/browser/aw_safe_browsing_resource_throttle.cc
+++ b/android_webview/browser/aw_safe_browsing_resource_throttle.cc
@@ -4,9 +4,9 @@
 
 #include "android_webview/browser/aw_safe_browsing_resource_throttle.h"
 
+#include "android_webview/browser/aw_safe_browsing_ui_manager.h"
 #include "base/macros.h"
 #include "components/safe_browsing/base_resource_throttle.h"
-#include "components/safe_browsing/base_ui_manager.h"
 #include "components/safe_browsing_db/database_manager.h"
 #include "components/security_interstitials/content/unsafe_resource.h"
 #include "content/public/common/resource_type.h"
@@ -20,7 +20,7 @@
     net::URLRequest* request,
     content::ResourceType resource_type,
     scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager,
-    scoped_refptr<safe_browsing::BaseUIManager> ui_manager) {
+    scoped_refptr<AwSafeBrowsingUIManager> ui_manager) {
   if (database_manager->IsSupported()) {
     return new AwSafeBrowsingResourceThrottle(request, resource_type,
                                               database_manager, ui_manager);
@@ -32,7 +32,7 @@
     net::URLRequest* request,
     content::ResourceType resource_type,
     scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager,
-    scoped_refptr<safe_browsing::BaseUIManager> ui_manager)
+    scoped_refptr<AwSafeBrowsingUIManager> ui_manager)
     : safe_browsing::BaseResourceThrottle(request,
                                           resource_type,
                                           database_manager,
diff --git a/android_webview/browser/aw_safe_browsing_resource_throttle.h b/android_webview/browser/aw_safe_browsing_resource_throttle.h
index cdaf6ad..5fbd4dd8 100644
--- a/android_webview/browser/aw_safe_browsing_resource_throttle.h
+++ b/android_webview/browser/aw_safe_browsing_resource_throttle.h
@@ -5,9 +5,9 @@
 #ifndef ANDROID_WEBVIEW_BROWSER_AW_SAFE_BROWSING_RESOURCE_THROTTLE_H_
 #define ANDROID_WEBVIEW_BROWSER_AW_SAFE_BROWSING_RESOURCE_THROTTLE_H_
 
+#include "android_webview/browser/aw_safe_browsing_ui_manager.h"
 #include "base/macros.h"
 #include "components/safe_browsing/base_resource_throttle.h"
-#include "components/safe_browsing/base_ui_manager.h"
 #include "components/safe_browsing_db/database_manager.h"
 #include "components/security_interstitials/content/unsafe_resource.h"
 #include "content/public/common/resource_type.h"
@@ -28,7 +28,7 @@
       content::ResourceType resource_type,
       scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
           database_manager,
-      scoped_refptr<safe_browsing::BaseUIManager> ui_manager);
+      scoped_refptr<AwSafeBrowsingUIManager> ui_manager);
 
  private:
   AwSafeBrowsingResourceThrottle(
@@ -36,7 +36,7 @@
       content::ResourceType resource_type,
       scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
           database_manager,
-      scoped_refptr<safe_browsing::BaseUIManager> ui_manager);
+      scoped_refptr<AwSafeBrowsingUIManager> ui_manager);
 
   ~AwSafeBrowsingResourceThrottle() override;
 
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
index 782747b..3e1ed55 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
@@ -87,6 +87,9 @@
     private static final String VERSION_CODE_PREF = "lastVersionCodeUsed";
     private static final String COMMAND_LINE_FILE = "/data/local/tmp/webview-command-line";
     private static final String HTTP_AUTH_DATABASE_FILE = "http_auth.db";
+    // same switch as kEnableCrashReporterForTesting in //base/base_switches.h
+    public static final String CRASH_UPLOADS_ENABLED_FOR_TESTING_SWITCH =
+            "enable-crash-reporter-for-testing";
 
     private class WebViewChromiumRunQueue {
         public WebViewChromiumRunQueue() {
@@ -423,13 +426,23 @@
         final boolean isExternalService = true;
         AwBrowserProcess.configureChildProcessLauncher(webViewPackageName, isExternalService);
         AwBrowserProcess.start();
-        AwBrowserProcess.handleMinidumps(webViewPackageName);
 
+        final boolean enableMinidumpUploadingForTesting = CommandLine.getInstance().hasSwitch(
+                CRASH_UPLOADS_ENABLED_FOR_TESTING_SWITCH);
+        if (enableMinidumpUploadingForTesting) {
+            AwBrowserProcess.handleMinidumps(webViewPackageName, true /* enabled */);
+        }
+
+        // Actions conditioned on whether the Android Checkbox is toggled on
         PlatformServiceBridge.getInstance(context)
                 .queryMetricsSetting(new ValueCallback<Boolean>() {
                     public void onReceiveValue(Boolean enabled) {
                         ThreadUtils.assertOnUiThread();
                         AwMetricsServiceClient.setConsentSetting(context, enabled);
+
+                        if (!enableMinidumpUploadingForTesting) {
+                            AwBrowserProcess.handleMinidumps(webViewPackageName, enabled);
+                        }
                     }
                 });
 
diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
index 7e1d8c59..a82a4c32 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
@@ -160,8 +160,11 @@
      * Pass Minidumps to a separate Service declared in the WebView provider package.
      * That Service will copy the Minidumps to its own data directory - at which point we can delete
      * our copies in the app directory.
+     * @param userApproved whether we have user consent to upload crash data - if we do, copy the
+     * minidumps, if we don't, delete them.
      */
-    public static void handleMinidumps(final String webViewPackageName) {
+    public static void handleMinidumps(
+            final String webViewPackageName, final boolean userApproved) {
         new AsyncTask<Void, Void, Void>() {
             @Override
             protected Void doInBackground(Void... params) {
@@ -173,6 +176,16 @@
                         crashFileManager.getAllMinidumpFiles(MAX_MINIDUMP_UPLOAD_TRIES);
                 if (minidumpFiles.length == 0) return null;
 
+                // Delete the minidumps if the user doesn't allow crash data uploading.
+                if (!userApproved) {
+                    for (File minidump : minidumpFiles) {
+                        if (!minidump.delete()) {
+                            Log.w(TAG, "Couldn't delete file " + minidump.getAbsolutePath());
+                        }
+                    }
+                    return null;
+                }
+
                 final Intent intent = new Intent();
                 intent.setClassName(webViewPackageName, CrashReceiverService.class.getName());
 
diff --git a/android_webview/java/src/org/chromium/android_webview/crash/CrashReceiverService.java b/android_webview/java/src/org/chromium/android_webview/crash/CrashReceiverService.java
index f3b994e..53d68974 100644
--- a/android_webview/java/src/org/chromium/android_webview/crash/CrashReceiverService.java
+++ b/android_webview/java/src/org/chromium/android_webview/crash/CrashReceiverService.java
@@ -44,26 +44,14 @@
     private Object mCopyingLock = new Object();
     private boolean mIsCopying = false;
 
-    // same switch as kEnableCrashReporterForTesting in //base/base_switches.h
-    static final String CRASH_UPLOADS_ENABLED_FOR_TESTING_SWITCH =
-            "enable-crash-reporter-for-testing";
-
     @Override
     public void onCreate() {
         super.onCreate();
-        SynchronizedWebViewCommandLine.initOnSeparateThread();
     }
 
     private final ICrashReceiverService.Stub mBinder = new ICrashReceiverService.Stub() {
         @Override
         public void transmitCrashes(ParcelFileDescriptor[] fileDescriptors) {
-            // TODO(gsennton): replace this check with a check for Android Checkbox when we have
-            // access to that value through GmsCore.
-            if (!SynchronizedWebViewCommandLine.hasSwitch(
-                        CRASH_UPLOADS_ENABLED_FOR_TESTING_SWITCH)) {
-                Log.i(TAG, "Crash reporting is not enabled, bailing!");
-                return;
-            }
             int uid = Binder.getCallingUid();
             performMinidumpCopyingSerially(
                     CrashReceiverService.this, uid, fileDescriptors, true /* scheduleUploads */);
diff --git a/android_webview/java/src/org/chromium/android_webview/crash/MinidumpUploadJobService.java b/android_webview/java/src/org/chromium/android_webview/crash/MinidumpUploadJobService.java
index 529ee32..841ae36d 100644
--- a/android_webview/java/src/org/chromium/android_webview/crash/MinidumpUploadJobService.java
+++ b/android_webview/java/src/org/chromium/android_webview/crash/MinidumpUploadJobService.java
@@ -23,7 +23,6 @@
     @Override
     public void onCreate() {
         super.onCreate();
-        SynchronizedWebViewCommandLine.initOnSeparateThread();
     }
 
     @Override
diff --git a/android_webview/java/src/org/chromium/android_webview/crash/MinidumpUploaderImpl.java b/android_webview/java/src/org/chromium/android_webview/crash/MinidumpUploaderImpl.java
index 7d9ed32..9c7b4a5 100644
--- a/android_webview/java/src/org/chromium/android_webview/crash/MinidumpUploaderImpl.java
+++ b/android_webview/java/src/org/chromium/android_webview/crash/MinidumpUploaderImpl.java
@@ -105,14 +105,15 @@
             }
             @Override
             public boolean isUsageAndCrashReportingPermittedByUser() {
-                // TODO(gsennton): make this depend on Android Checkbox when we can read that
-                // through GmsCore.
-                return false;
+                // We ensure we have user permission before copying minidumps to the directory used
+                // by this process - so always return true here.
+                return true;
             }
             @Override
             public boolean isUploadEnabledForTests() {
-                return SynchronizedWebViewCommandLine.hasSwitch(
-                        CrashReceiverService.CRASH_UPLOADS_ENABLED_FOR_TESTING_SWITCH);
+                // We are already checking whether this feature is enabled for manual testing before
+                // copying minidumps.
+                return false;
             }
         };
     }
@@ -165,7 +166,7 @@
 
     @Override
     public void uploadAllMinidumps(
-            MinidumpUploader.UploadsFinishedCallback uploadsFinishedCallback) {
+            final MinidumpUploader.UploadsFinishedCallback uploadsFinishedCallback) {
         if (mWorkerThread != null) {
             throw new RuntimeException("Only one upload-job should be active at a time");
         }
diff --git a/android_webview/java/src/org/chromium/android_webview/crash/SynchronizedWebViewCommandLine.java b/android_webview/java/src/org/chromium/android_webview/crash/SynchronizedWebViewCommandLine.java
deleted file mode 100644
index 27331a89..0000000
--- a/android_webview/java/src/org/chromium/android_webview/crash/SynchronizedWebViewCommandLine.java
+++ /dev/null
@@ -1,59 +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.
-
-package org.chromium.android_webview.crash;
-
-import org.chromium.base.CommandLine;
-import org.chromium.base.annotations.SuppressFBWarnings;
-
-/**
- * Class for fetching command line switches for WebView in a thread-safe way.
- */
-class SynchronizedWebViewCommandLine {
-    private static final Object sLock = new Object();
-    private static InitState sInitialized = InitState.NOT_STARTED;
-    // TODO(gsennton): this value is used in WebViewChromiumFactoryProvider as well - set it
-    // somewhere where it can be read from both classes.
-    private static final String WEBVIEW_COMMAND_LINE_FILE = "/data/local/tmp/webview-command-line";
-
-    private enum InitState { NOT_STARTED, STARTED, DONE }
-
-    /**
-     * Initialize the global CommandLine using the WebView command line file.
-     * This method includes IO operations - it shouldn't be performed on the main thread.
-     */
-    public static void initOnSeparateThread() {
-        synchronized (sLock) {
-            if (sInitialized != InitState.NOT_STARTED) return;
-            sInitialized = InitState.STARTED;
-        }
-        new Thread(new Runnable() {
-            @SuppressFBWarnings("DMI_HARDCODED_ABSOLUTE_FILENAME")
-            @Override
-            public void run() {
-                CommandLine.initFromFile(WEBVIEW_COMMAND_LINE_FILE);
-                synchronized (sLock) {
-                    sInitialized = InitState.DONE;
-                    sLock.notifyAll();
-                }
-            }
-        }, "WebView-command-line-init-thread").start();
-    }
-
-    /**
-     * Returns true if this command line contains the given switch.
-     */
-    public static boolean hasSwitch(String switchString) {
-        synchronized (sLock) {
-            while (sInitialized != InitState.DONE) {
-                try {
-                    sLock.wait();
-                } catch (InterruptedException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-            return CommandLine.getInstance().hasSwitch(switchString);
-        }
-    }
-}
diff --git a/ash/common/ash_switches.cc b/ash/common/ash_switches.cc
index d912f149..3141b2c4 100644
--- a/ash/common/ash_switches.cc
+++ b/ash/common/ash_switches.cc
@@ -68,11 +68,6 @@
 // Enables mirrored screen.
 const char kAshEnableMirroredScreen[] = "ash-enable-mirrored-screen";
 
-// Enables touch view testing.
-// TODO(skuhne): Remove DEBUG_TOGGLE_TOUCH_VIEW accelerator once this flag is
-// removed.
-const char kAshEnableTouchViewTesting[] = "ash-enable-touch-view-testing";
-
 // Hides notifications that are irrelevant to Chrome OS device factory testing,
 // such as battery level updates.
 const char kAshHideNotificationsForFactory[] =
diff --git a/ash/common/ash_switches.h b/ash/common/ash_switches.h
index 28f4430f..ee10c85 100644
--- a/ash/common/ash_switches.h
+++ b/ash/common/ash_switches.h
@@ -31,7 +31,6 @@
 ASH_EXPORT extern const char kAshEnableTouchView[];
 ASH_EXPORT extern const char kAshEnableMirroredScreen[];
 ASH_EXPORT extern const char kAshDisableStableOverviewOrder[];
-ASH_EXPORT extern const char kAshEnableTouchViewTesting[];
 ASH_EXPORT extern const char kAshHideNotificationsForFactory[];
 ASH_EXPORT extern const char kAshMaterialDesign[];
 ASH_EXPORT extern const char kAshMaterialDesignDisabled[];
diff --git a/ash/common/wm/maximize_mode/maximize_mode_controller.cc b/ash/common/wm/maximize_mode/maximize_mode_controller.cc
index e0dced60..e83d321 100644
--- a/ash/common/wm/maximize_mode/maximize_mode_controller.cc
+++ b/ash/common/wm/maximize_mode/maximize_mode_controller.cc
@@ -98,24 +98,21 @@
   // unavailable. This will require refactoring
   // IsMaximizeModeWindowManagerEnabled to check for the existance of the
   // controller.
-  const bool is_enabled = IsEnabled();
-  if (is_enabled)
+  if (IsEnabled()) {
     WmShell::Get()->AddDisplayObserver(this);
-
-  if (is_enabled)
     chromeos::AccelerometerReader::GetInstance()->AddObserver(this);
+  }
   chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
       this);
 }
 
 MaximizeModeController::~MaximizeModeController() {
   WmShell::Get()->RemoveShellObserver(this);
-  const bool is_enabled = IsEnabled();
-  if (is_enabled)
-    WmShell::Get()->RemoveDisplayObserver(this);
 
-  if (is_enabled)
+  if (IsEnabled()) {
+    WmShell::Get()->RemoveDisplayObserver(this);
     chromeos::AccelerometerReader::GetInstance()->RemoveObserver(this);
+  }
   chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
       this);
 }
@@ -123,15 +120,8 @@
 bool MaximizeModeController::CanEnterMaximizeMode() {
   // If we have ever seen accelerometer data, then HandleHingeRotation may
   // trigger maximize mode at some point in the future.
-  // The --enable-touch-view-testing switch can also mean that we may enter
-  // maximize mode.
-  // TODO(mgiuca): This can result in false positives, as it returns true for
-  // any device with an accelerometer. Have TouchView-enabled devices explicitly
-  // set a flag, and change this implementation to simply return true iff the
-  // flag is present (http://crbug.com/457445).
-  return have_seen_accelerometer_data_ ||
-         base::CommandLine::ForCurrentProcess()->HasSwitch(
-             switches::kAshEnableTouchViewTesting);
+  // All TouchView-enabled devices can enter maximized mode.
+  return have_seen_accelerometer_data_ || IsEnabled();
 }
 
 // TODO(jcliang): Hide or remove EnableMaximizeModeWindowManager
@@ -322,13 +312,6 @@
   event_blocker_ =
       WmShell::Get()->CreateScopedDisableInternalMouseAndKeyboard();
 
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kAshEnableTouchViewTesting)) {
-    // We don't let accelerometer updates interfere with the maximize mode
-    // status as set by the touch-view-testing keyboard shortcut.
-    return;
-  }
-
   if (IsMaximizeModeWindowManagerEnabled())
     return;
   EnableMaximizeModeWindowManager(true);
@@ -337,13 +320,6 @@
 void MaximizeModeController::LeaveMaximizeMode() {
   event_blocker_.reset();
 
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kAshEnableTouchViewTesting)) {
-    // We don't let accelerometer updates interfere with the maximize mode
-    // status as set by the touch-view-testing keyboard shortcut.
-    return;
-  }
-
   if (!IsMaximizeModeWindowManagerEnabled())
     return;
   EnableMaximizeModeWindowManager(false);
diff --git a/ash/content/display/screen_orientation_controller_chromeos_unittest.cc b/ash/content/display/screen_orientation_controller_chromeos_unittest.cc
index fe157480..c388d0ed 100644
--- a/ash/content/display/screen_orientation_controller_chromeos_unittest.cc
+++ b/ash/content/display/screen_orientation_controller_chromeos_unittest.cc
@@ -161,8 +161,6 @@
 void ScreenOrientationControllerTest::SetUp() {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       ::switches::kUseFirstDisplayAsInternal);
-  base::CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kAshEnableTouchViewTesting);
   test::AshTestBase::SetUp();
 }
 
diff --git a/ash/host/ash_window_tree_host_x11.cc b/ash/host/ash_window_tree_host_x11.cc
index d904bee..e4bf384 100644
--- a/ash/host/ash_window_tree_host_x11.cc
+++ b/ash/host/ash_window_tree_host_x11.cc
@@ -197,7 +197,8 @@
       // space so the bounds check will not work so well.
       if (touch_display_id == display::kInvalidDisplayId) {
         if (base::SysInfo::IsRunningOnChromeOS() &&
-            !bounds().Contains(ui::EventLocationFromNative(xev)))
+            !bounds().Contains(
+                gfx::ToFlooredPoint(ui::EventLocationFromNative(xev))))
           return false;
       } else {
         display::Screen* screen = display::Screen::GetScreen();
diff --git a/ash/mus/top_level_window_factory.cc b/ash/mus/top_level_window_factory.cc
index f3260d0d..5da13441 100644
--- a/ash/mus/top_level_window_factory.cc
+++ b/ash/mus/top_level_window_factory.cc
@@ -21,6 +21,7 @@
 #include "services/ui/public/interfaces/window_manager_constants.mojom.h"
 #include "ui/aura/mus/property_converter.h"
 #include "ui/aura/mus/property_utils.h"
+#include "ui/aura/mus/window_tree_client.h"
 #include "ui/aura/window.h"
 #include "ui/display/display.h"
 
@@ -186,6 +187,17 @@
     // No need to persist this value.
     properties->erase(ui::mojom::WindowManager::kWindowIgnoredByShelf_Property);
   }
+  if (properties->count(ui::mojom::WindowManager::kFocusable_InitProperty)) {
+    bool can_focus = mojo::ConvertTo<bool>(
+        (*properties)[ui::mojom::WindowManager::kFocusable_InitProperty]);
+    window_manager->window_tree_client()->SetCanFocus(window, can_focus);
+    NonClientFrameController* non_client_frame_controller =
+        NonClientFrameController::Get(window);
+    if (non_client_frame_controller)
+      non_client_frame_controller->set_can_activate(can_focus);
+    // No need to persist this value.
+    properties->erase(ui::mojom::WindowManager::kFocusable_InitProperty);
+  }
   return window;
 }
 
diff --git a/ash/mus/window_manager.cc b/ash/mus/window_manager.cc
index 8d7f21e..8ef14a1 100644
--- a/ash/mus/window_manager.cc
+++ b/ash/mus/window_manager.cc
@@ -321,6 +321,13 @@
          name == ui::mojom::WindowManager::kWindowTitle_Property;
 }
 
+void WindowManager::OnWmSetCanFocus(aura::Window* window, bool can_focus) {
+  NonClientFrameController* non_client_frame_controller =
+      NonClientFrameController::Get(window);
+  if (non_client_frame_controller)
+    non_client_frame_controller->set_can_activate(can_focus);
+}
+
 aura::Window* WindowManager::OnWmCreateTopLevelWindow(
     ui::mojom::WindowType window_type,
     std::map<std::string, std::vector<uint8_t>>* properties) {
diff --git a/ash/mus/window_manager.h b/ash/mus/window_manager.h
index 6936f926..bd9b8b54 100644
--- a/ash/mus/window_manager.h
+++ b/ash/mus/window_manager.h
@@ -142,6 +142,7 @@
       aura::Window* window,
       const std::string& name,
       std::unique_ptr<std::vector<uint8_t>>* new_data) override;
+  void OnWmSetCanFocus(aura::Window* window, bool can_focus) override;
   aura::Window* OnWmCreateTopLevelWindow(
       ui::mojom::WindowType window_type,
       std::map<std::string, std::vector<uint8_t>>* properties) override;
diff --git a/ash/system/chromeos/power/tablet_power_button_controller.cc b/ash/system/chromeos/power/tablet_power_button_controller.cc
index cb0a7f1..fb5c1393 100644
--- a/ash/system/chromeos/power/tablet_power_button_controller.cc
+++ b/ash/system/chromeos/power/tablet_power_button_controller.cc
@@ -29,8 +29,7 @@
 // ignored.
 constexpr int kIgnorePowerButtonAfterResumeMs = 2000;
 
-// Returns true if device is a convertible/tablet device or has
-// kAshEnableTouchViewTesting in test, otherwise false.
+// Returns true if device is a convertible/tablet device, otherwise false.
 bool IsTabletModeSupported() {
   MaximizeModeController* maximize_mode_controller =
       WmShell::Get()->maximize_mode_controller();
diff --git a/ash/system/chromeos/power/tablet_power_button_controller_unittest.cc b/ash/system/chromeos/power/tablet_power_button_controller_unittest.cc
index a115f49..2dcc5ec 100644
--- a/ash/system/chromeos/power/tablet_power_button_controller_unittest.cc
+++ b/ash/system/chromeos/power/tablet_power_button_controller_unittest.cc
@@ -52,7 +52,7 @@
     power_manager_client_ = new chromeos::FakePowerManagerClient();
     dbus_setter->SetPowerManagerClient(base::WrapUnique(power_manager_client_));
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
-        switches::kAshEnableTouchViewTesting);
+        switches::kAshEnableTouchView);
     AshTestBase::SetUp();
 
     lock_state_controller_ = Shell::GetInstance()->lock_state_controller();
diff --git a/ash/touch/touch_uma.cc b/ash/touch/touch_uma.cc
index c2666aaf..32bf2de7 100644
--- a/ash/touch/touch_uma.cc
+++ b/ash/touch/touch_uma.cc
@@ -104,7 +104,8 @@
 
   // Prefer raw event location (when available) over calibrated location.
   if (event.HasNativeEvent()) {
-    position = ui::EventLocationFromNative(event.native_event());
+    position =
+        gfx::ToFlooredPoint(ui::EventLocationFromNative(event.native_event()));
     position = gfx::ScaleToFlooredPoint(
         position, 1.f / target->layer()->device_scale_factor());
   }
diff --git a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
index f627dff5..2bd0958 100644
--- a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
+++ b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
@@ -445,16 +445,6 @@
   }
 }
 
-// Tests that CanEnterMaximizeMode returns false until a valid accelerometer
-// event has been received, and that it returns true afterwards.
-TEST_F(MaximizeModeControllerTest,
-       CanEnterMaximizeModeRequiresValidAccelerometerUpdate) {
-  // Should be false until an accelerometer event is sent.
-  ASSERT_FALSE(maximize_mode_controller()->CanEnterMaximizeMode());
-  OpenLidToAngle(90.0f);
-  EXPECT_TRUE(maximize_mode_controller()->CanEnterMaximizeMode());
-}
-
 // Tests that when an accelerometer event is received which has no keyboard that
 // we enter maximize mode.
 TEST_F(MaximizeModeControllerTest,
@@ -577,29 +567,4 @@
   }
 }
 
-class MaximizeModeControllerSwitchesTest : public MaximizeModeControllerTest {
- public:
-  MaximizeModeControllerSwitchesTest() {}
-  ~MaximizeModeControllerSwitchesTest() override {}
-
-  void SetUp() override {
-    base::CommandLine::ForCurrentProcess()->AppendSwitch(
-        switches::kAshEnableTouchViewTesting);
-    MaximizeModeControllerTest::SetUp();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MaximizeModeControllerSwitchesTest);
-};
-
-// Tests that when the command line switch for testing maximize mode is on, that
-// accelerometer updates which would normally cause it to exit do not.
-TEST_F(MaximizeModeControllerSwitchesTest, IgnoreHingeAngles) {
-  maximize_mode_controller()->EnableMaximizeModeWindowManager(true);
-
-  // Would normally trigger an exit from maximize mode.
-  OpenLidToAngle(90.0f);
-  EXPECT_TRUE(IsMaximizeModeStarted());
-}
-
 }  // namespace ash
diff --git a/ash/wm/power_button_controller.cc b/ash/wm/power_button_controller.cc
index 6b1303e..104d612 100644
--- a/ash/wm/power_button_controller.cc
+++ b/ash/wm/power_button_controller.cc
@@ -39,9 +39,7 @@
   chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
       this);
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kAshEnableTouchView) ||
-      base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kAshEnableTouchViewTesting)) {
+          switches::kAshEnableTouchView)) {
     tablet_controller_.reset(
         new TabletPowerButtonController(lock_state_controller_));
   }
diff --git a/ash/wm/session_state_animator.cc b/ash/wm/session_state_animator.cc
index 73ddd43..04695f6c 100644
--- a/ash/wm/session_state_animator.cc
+++ b/ash/wm/session_state_animator.cc
@@ -22,9 +22,7 @@
 
 bool IsTouchViewEnabled() {
   return base::CommandLine::ForCurrentProcess()->HasSwitch(
-             switches::kAshEnableTouchView) ||
-         base::CommandLine::ForCurrentProcess()->HasSwitch(
-             switches::kAshEnableTouchViewTesting);
+      switches::kAshEnableTouchView);
 }
 
 }  // namespace
diff --git a/base/BUILD.gn b/base/BUILD.gn
index fa5e369d..7f46e71 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -149,6 +149,8 @@
     "allocator/allocator_check.h",
     "allocator/allocator_extension.cc",
     "allocator/allocator_extension.h",
+    "allocator/allocator_interception_mac.h",
+    "allocator/allocator_interception_mac.mm",
     "allocator/allocator_shim.h",
     "allocator/oom.h",
     "android/animation_frame_time_histogram.cc",
diff --git a/base/allocator/allocator_interception_mac.h b/base/allocator/allocator_interception_mac.h
new file mode 100644
index 0000000..87cbf489
--- /dev/null
+++ b/base/allocator/allocator_interception_mac.h
@@ -0,0 +1,55 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_ALLOCATOR_ALLOCATOR_INTERCEPTION_MAC_H_
+#define BASE_ALLOCATOR_ALLOCATOR_INTERCEPTION_MAC_H_
+
+#include <malloc/malloc.h>
+#include <stddef.h>
+
+#include "third_party/apple_apsl/malloc.h"
+
+namespace base {
+namespace allocator {
+
+typedef void* (*malloc_type)(struct _malloc_zone_t* zone, size_t size);
+typedef void* (*calloc_type)(struct _malloc_zone_t* zone,
+                             size_t num_items,
+                             size_t size);
+typedef void* (*valloc_type)(struct _malloc_zone_t* zone, size_t size);
+typedef void (*free_type)(struct _malloc_zone_t* zone, void* ptr);
+typedef void* (*realloc_type)(struct _malloc_zone_t* zone,
+                              void* ptr,
+                              size_t size);
+typedef void* (*memalign_type)(struct _malloc_zone_t* zone,
+                               size_t alignment,
+                               size_t size);
+
+struct MallocZoneFunctions {
+  malloc_type malloc = nullptr;
+  calloc_type calloc = nullptr;
+  valloc_type valloc = nullptr;
+  free_type free = nullptr;
+  realloc_type realloc = nullptr;
+  memalign_type memalign = nullptr;
+};
+
+// Saves the function pointers currently used by |zone| into |functions|.
+void StoreZoneFunctions(ChromeMallocZone* zone, MallocZoneFunctions* functions);
+
+// Updates the malloc zone to use the functions specified by |functions|.
+void ReplaceZoneFunctions(ChromeMallocZone* zone,
+                          const MallocZoneFunctions* functions);
+
+// Calls the original implementation of malloc/calloc prior to interception.
+bool UncheckedMallocMac(size_t size, void** result);
+bool UncheckedCallocMac(size_t num_items, size_t size, void** result);
+
+// Intercepts calls to default and purgeable malloc zones. Intercepts Core
+// Foundation and Objective-C allocations.
+void InterceptAllocationsMac();
+}  // namespace allocator
+}  // namespace base
+
+#endif  // BASE_ALLOCATOR_ALLOCATOR_INTERCEPTION_MAC_H_
diff --git a/base/allocator/allocator_interception_mac.mm b/base/allocator/allocator_interception_mac.mm
new file mode 100644
index 0000000..11ee3ed
--- /dev/null
+++ b/base/allocator/allocator_interception_mac.mm
@@ -0,0 +1,471 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file contains all the logic necessary to intercept allocations on
+// macOS. "malloc zones" are an abstraction that allows the process to intercept
+// all malloc-related functions.  There is no good mechanism [short of
+// interposition] to determine new malloc zones are added, so there's no clean
+// mechanism to intercept all malloc zones. This file contains logic to
+// intercept the default and purgeable zones, which always exist. A cursory
+// review of Chrome seems to imply that non-default zones are almost never used.
+//
+// This file also contains logic to intercept Core Foundation and Objective-C
+// allocations. The implementations forward to the default malloc zone, so the
+// only reason to intercept these calls is to re-label OOM crashes with slightly
+// more details.
+
+#include "base/allocator/allocator_interception_mac.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#import <Foundation/Foundation.h>
+#include <errno.h>
+#include <mach/mach.h>
+#include <mach/mach_vm.h>
+#import <objc/runtime.h>
+#include <stddef.h>
+
+#include <new>
+
+#include "base/logging.h"
+#include "base/mac/mac_util.h"
+#include "base/mac/mach_logging.h"
+#include "base/process/memory.h"
+#include "base/scoped_clear_errno.h"
+#include "build/build_config.h"
+#include "third_party/apple_apsl/CFBase.h"
+
+namespace base {
+namespace allocator {
+
+namespace {
+
+bool g_oom_killer_enabled;
+
+// Starting with Mac OS X 10.7, the zone allocators set up by the system are
+// read-only, to prevent them from being overwritten in an attack. However,
+// blindly unprotecting and reprotecting the zone allocators fails with
+// GuardMalloc because GuardMalloc sets up its zone allocator using a block of
+// memory in its bss. Explicit saving/restoring of the protection is required.
+//
+// This function takes a pointer to a malloc zone, de-protects it if necessary,
+// and returns (in the out parameters) a region of memory (if any) to be
+// re-protected when modifications are complete. This approach assumes that
+// there is no contention for the protection of this memory.
+void DeprotectMallocZone(ChromeMallocZone* default_zone,
+                         mach_vm_address_t* reprotection_start,
+                         mach_vm_size_t* reprotection_length,
+                         vm_prot_t* reprotection_value) {
+  mach_port_t unused;
+  *reprotection_start = reinterpret_cast<mach_vm_address_t>(default_zone);
+  struct vm_region_basic_info_64 info;
+  mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
+  kern_return_t result = mach_vm_region(
+      mach_task_self(), reprotection_start, reprotection_length,
+      VM_REGION_BASIC_INFO_64, reinterpret_cast<vm_region_info_t>(&info),
+      &count, &unused);
+  MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_region";
+
+  // The kernel always returns a null object for VM_REGION_BASIC_INFO_64, but
+  // balance it with a deallocate in case this ever changes. See 10.9.2
+  // xnu-2422.90.20/osfmk/vm/vm_map.c vm_map_region.
+  mach_port_deallocate(mach_task_self(), unused);
+
+  // Does the region fully enclose the zone pointers? Possibly unwarranted
+  // simplification used: using the size of a full version 8 malloc zone rather
+  // than the actual smaller size if the passed-in zone is not version 8.
+  CHECK(*reprotection_start <=
+        reinterpret_cast<mach_vm_address_t>(default_zone));
+  mach_vm_size_t zone_offset =
+      reinterpret_cast<mach_vm_size_t>(default_zone) -
+      reinterpret_cast<mach_vm_size_t>(*reprotection_start);
+  CHECK(zone_offset + sizeof(ChromeMallocZone) <= *reprotection_length);
+
+  if (info.protection & VM_PROT_WRITE) {
+    // No change needed; the zone is already writable.
+    *reprotection_start = 0;
+    *reprotection_length = 0;
+    *reprotection_value = VM_PROT_NONE;
+  } else {
+    *reprotection_value = info.protection;
+    result = mach_vm_protect(mach_task_self(), *reprotection_start,
+                             *reprotection_length, false,
+                             info.protection | VM_PROT_WRITE);
+    MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect";
+  }
+}
+
+#if !defined(ADDRESS_SANITIZER)
+
+MallocZoneFunctions g_old_zone;
+MallocZoneFunctions g_old_purgeable_zone;
+
+void* oom_killer_malloc(struct _malloc_zone_t* zone, size_t size) {
+  void* result = g_old_zone.malloc(zone, size);
+  if (!result && size)
+    TerminateBecauseOutOfMemory(size);
+  return result;
+}
+
+void* oom_killer_calloc(struct _malloc_zone_t* zone,
+                        size_t num_items,
+                        size_t size) {
+  void* result = g_old_zone.calloc(zone, num_items, size);
+  if (!result && num_items && size)
+    TerminateBecauseOutOfMemory(num_items * size);
+  return result;
+}
+
+void* oom_killer_valloc(struct _malloc_zone_t* zone, size_t size) {
+  void* result = g_old_zone.valloc(zone, size);
+  if (!result && size)
+    TerminateBecauseOutOfMemory(size);
+  return result;
+}
+
+void oom_killer_free(struct _malloc_zone_t* zone, void* ptr) {
+  g_old_zone.free(zone, ptr);
+}
+
+void* oom_killer_realloc(struct _malloc_zone_t* zone, void* ptr, size_t size) {
+  void* result = g_old_zone.realloc(zone, ptr, size);
+  if (!result && size)
+    TerminateBecauseOutOfMemory(size);
+  return result;
+}
+
+void* oom_killer_memalign(struct _malloc_zone_t* zone,
+                          size_t alignment,
+                          size_t size) {
+  void* result = g_old_zone.memalign(zone, alignment, size);
+  // Only die if posix_memalign would have returned ENOMEM, since there are
+  // other reasons why NULL might be returned (see
+  // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ).
+  if (!result && size && alignment >= sizeof(void*) &&
+      (alignment & (alignment - 1)) == 0) {
+    TerminateBecauseOutOfMemory(size);
+  }
+  return result;
+}
+
+void* oom_killer_malloc_purgeable(struct _malloc_zone_t* zone, size_t size) {
+  void* result = g_old_purgeable_zone.malloc(zone, size);
+  if (!result && size)
+    TerminateBecauseOutOfMemory(size);
+  return result;
+}
+
+void* oom_killer_calloc_purgeable(struct _malloc_zone_t* zone,
+                                  size_t num_items,
+                                  size_t size) {
+  void* result = g_old_purgeable_zone.calloc(zone, num_items, size);
+  if (!result && num_items && size)
+    TerminateBecauseOutOfMemory(num_items * size);
+  return result;
+}
+
+void* oom_killer_valloc_purgeable(struct _malloc_zone_t* zone, size_t size) {
+  void* result = g_old_purgeable_zone.valloc(zone, size);
+  if (!result && size)
+    TerminateBecauseOutOfMemory(size);
+  return result;
+}
+
+void oom_killer_free_purgeable(struct _malloc_zone_t* zone, void* ptr) {
+  g_old_purgeable_zone.free(zone, ptr);
+}
+
+void* oom_killer_realloc_purgeable(struct _malloc_zone_t* zone,
+                                   void* ptr,
+                                   size_t size) {
+  void* result = g_old_purgeable_zone.realloc(zone, ptr, size);
+  if (!result && size)
+    TerminateBecauseOutOfMemory(size);
+  return result;
+}
+
+void* oom_killer_memalign_purgeable(struct _malloc_zone_t* zone,
+                                    size_t alignment,
+                                    size_t size) {
+  void* result = g_old_purgeable_zone.memalign(zone, alignment, size);
+  // Only die if posix_memalign would have returned ENOMEM, since there are
+  // other reasons why NULL might be returned (see
+  // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ).
+  if (!result && size && alignment >= sizeof(void*) &&
+      (alignment & (alignment - 1)) == 0) {
+    TerminateBecauseOutOfMemory(size);
+  }
+  return result;
+}
+
+#endif  // !defined(ADDRESS_SANITIZER)
+
+// === C++ operator new ===
+
+void oom_killer_new() {
+  TerminateBecauseOutOfMemory(0);
+}
+
+#if !defined(ADDRESS_SANITIZER)
+
+// === Core Foundation CFAllocators ===
+
+bool CanGetContextForCFAllocator() {
+  return !base::mac::IsOSLaterThan10_12_DontCallThis();
+}
+
+CFAllocatorContext* ContextForCFAllocator(CFAllocatorRef allocator) {
+  ChromeCFAllocatorLions* our_allocator = const_cast<ChromeCFAllocatorLions*>(
+      reinterpret_cast<const ChromeCFAllocatorLions*>(allocator));
+  return &our_allocator->_context;
+}
+
+CFAllocatorAllocateCallBack g_old_cfallocator_system_default;
+CFAllocatorAllocateCallBack g_old_cfallocator_malloc;
+CFAllocatorAllocateCallBack g_old_cfallocator_malloc_zone;
+
+void* oom_killer_cfallocator_system_default(CFIndex alloc_size,
+                                            CFOptionFlags hint,
+                                            void* info) {
+  void* result = g_old_cfallocator_system_default(alloc_size, hint, info);
+  if (!result)
+    TerminateBecauseOutOfMemory(alloc_size);
+  return result;
+}
+
+void* oom_killer_cfallocator_malloc(CFIndex alloc_size,
+                                    CFOptionFlags hint,
+                                    void* info) {
+  void* result = g_old_cfallocator_malloc(alloc_size, hint, info);
+  if (!result)
+    TerminateBecauseOutOfMemory(alloc_size);
+  return result;
+}
+
+void* oom_killer_cfallocator_malloc_zone(CFIndex alloc_size,
+                                         CFOptionFlags hint,
+                                         void* info) {
+  void* result = g_old_cfallocator_malloc_zone(alloc_size, hint, info);
+  if (!result)
+    TerminateBecauseOutOfMemory(alloc_size);
+  return result;
+}
+
+#endif  // !defined(ADDRESS_SANITIZER)
+
+// === Cocoa NSObject allocation ===
+
+typedef id (*allocWithZone_t)(id, SEL, NSZone*);
+allocWithZone_t g_old_allocWithZone;
+
+id oom_killer_allocWithZone(id self, SEL _cmd, NSZone* zone) {
+  id result = g_old_allocWithZone(self, _cmd, zone);
+  if (!result)
+    TerminateBecauseOutOfMemory(0);
+  return result;
+}
+
+}  // namespace
+
+bool UncheckedMallocMac(size_t size, void** result) {
+#if defined(ADDRESS_SANITIZER)
+  *result = malloc(size);
+#else
+  if (g_old_zone.malloc) {
+    *result = g_old_zone.malloc(malloc_default_zone(), size);
+  } else {
+    *result = malloc(size);
+  }
+#endif  // defined(ADDRESS_SANITIZER)
+
+  return *result != NULL;
+}
+
+bool UncheckedCallocMac(size_t num_items, size_t size, void** result) {
+#if defined(ADDRESS_SANITIZER)
+  *result = calloc(num_items, size);
+#else
+  if (g_old_zone.calloc) {
+    *result = g_old_zone.calloc(malloc_default_zone(), num_items, size);
+  } else {
+    *result = calloc(num_items, size);
+  }
+#endif  // defined(ADDRESS_SANITIZER)
+
+  return *result != NULL;
+}
+
+void StoreZoneFunctions(ChromeMallocZone* zone,
+                        MallocZoneFunctions* functions) {
+  functions->malloc = zone->malloc;
+  functions->calloc = zone->calloc;
+  functions->valloc = zone->valloc;
+  functions->free = zone->free;
+  functions->realloc = zone->realloc;
+  CHECK(functions->malloc && functions->calloc && functions->valloc &&
+        functions->free && functions->realloc);
+
+  if (zone->version >= 5) {
+    functions->memalign = zone->memalign;
+    CHECK(functions->memalign);
+  }
+}
+
+void ReplaceZoneFunctions(ChromeMallocZone* zone,
+                          const MallocZoneFunctions* functions) {
+  // Remove protection.
+  mach_vm_address_t reprotection_start = 0;
+  mach_vm_size_t reprotection_length = 0;
+  vm_prot_t reprotection_value = VM_PROT_NONE;
+  DeprotectMallocZone(zone, &reprotection_start, &reprotection_length,
+                      &reprotection_value);
+
+  zone->malloc = functions->malloc;
+  zone->calloc = functions->calloc;
+  zone->valloc = functions->valloc;
+  zone->free = functions->free;
+  zone->realloc = functions->realloc;
+  if (zone->version >= 5) {
+    zone->memalign = functions->memalign;
+  }
+
+  // Restore protection if it was active.
+  if (reprotection_start) {
+    kern_return_t result =
+        mach_vm_protect(mach_task_self(), reprotection_start,
+                        reprotection_length, false, reprotection_value);
+    MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect";
+  }
+}
+
+void InterceptAllocationsMac() {
+  if (g_oom_killer_enabled)
+    return;
+
+  g_oom_killer_enabled = true;
+
+// === C malloc/calloc/valloc/realloc/posix_memalign ===
+
+// This approach is not perfect, as requests for amounts of memory larger than
+// MALLOC_ABSOLUTE_MAX_SIZE (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will
+// still fail with a NULL rather than dying (see
+// http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c for details).
+// Unfortunately, it's the best we can do. Also note that this does not affect
+// allocations from non-default zones.
+
+#if !defined(ADDRESS_SANITIZER)
+  // Don't do anything special on OOM for the malloc zones replaced by
+  // AddressSanitizer, as modifying or protecting them may not work correctly.
+  ChromeMallocZone* default_zone =
+      reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
+  StoreZoneFunctions(default_zone, &g_old_zone);
+  MallocZoneFunctions new_functions;
+  new_functions.malloc = oom_killer_malloc;
+  new_functions.calloc = oom_killer_calloc;
+  new_functions.valloc = oom_killer_valloc;
+  new_functions.free = oom_killer_free;
+  new_functions.realloc = oom_killer_realloc;
+  new_functions.memalign = oom_killer_memalign;
+  ReplaceZoneFunctions(default_zone, &new_functions);
+
+  ChromeMallocZone* purgeable_zone =
+      reinterpret_cast<ChromeMallocZone*>(malloc_default_purgeable_zone());
+  if (purgeable_zone) {
+    StoreZoneFunctions(purgeable_zone, &g_old_purgeable_zone);
+    MallocZoneFunctions new_functions;
+    new_functions.malloc = oom_killer_malloc_purgeable;
+    new_functions.calloc = oom_killer_calloc_purgeable;
+    new_functions.valloc = oom_killer_valloc_purgeable;
+    new_functions.free = oom_killer_free_purgeable;
+    new_functions.realloc = oom_killer_realloc_purgeable;
+    new_functions.memalign = oom_killer_memalign_purgeable;
+    ReplaceZoneFunctions(purgeable_zone, &new_functions);
+  }
+#endif
+
+  // === C malloc_zone_batch_malloc ===
+
+  // batch_malloc is omitted because the default malloc zone's implementation
+  // only supports batch_malloc for "tiny" allocations from the free list. It
+  // will fail for allocations larger than "tiny", and will only allocate as
+  // many blocks as it's able to from the free list. These factors mean that it
+  // can return less than the requested memory even in a non-out-of-memory
+  // situation. There's no good way to detect whether a batch_malloc failure is
+  // due to these other factors, or due to genuine memory or address space
+  // exhaustion. The fact that it only allocates space from the "tiny" free list
+  // means that it's likely that a failure will not be due to memory exhaustion.
+  // Similarly, these constraints on batch_malloc mean that callers must always
+  // be expecting to receive less memory than was requested, even in situations
+  // where memory pressure is not a concern. Finally, the only public interface
+  // to batch_malloc is malloc_zone_batch_malloc, which is specific to the
+  // system's malloc implementation. It's unlikely that anyone's even heard of
+  // it.
+
+  // === C++ operator new ===
+
+  // Yes, operator new does call through to malloc, but this will catch failures
+  // that our imperfect handling of malloc cannot.
+
+  std::set_new_handler(oom_killer_new);
+
+#ifndef ADDRESS_SANITIZER
+  // === Core Foundation CFAllocators ===
+
+  // This will not catch allocation done by custom allocators, but will catch
+  // all allocation done by system-provided ones.
+
+  CHECK(!g_old_cfallocator_system_default && !g_old_cfallocator_malloc &&
+        !g_old_cfallocator_malloc_zone)
+      << "Old allocators unexpectedly non-null";
+
+  bool cf_allocator_internals_known = CanGetContextForCFAllocator();
+
+  if (cf_allocator_internals_known) {
+    CFAllocatorContext* context =
+        ContextForCFAllocator(kCFAllocatorSystemDefault);
+    CHECK(context) << "Failed to get context for kCFAllocatorSystemDefault.";
+    g_old_cfallocator_system_default = context->allocate;
+    CHECK(g_old_cfallocator_system_default)
+        << "Failed to get kCFAllocatorSystemDefault allocation function.";
+    context->allocate = oom_killer_cfallocator_system_default;
+
+    context = ContextForCFAllocator(kCFAllocatorMalloc);
+    CHECK(context) << "Failed to get context for kCFAllocatorMalloc.";
+    g_old_cfallocator_malloc = context->allocate;
+    CHECK(g_old_cfallocator_malloc)
+        << "Failed to get kCFAllocatorMalloc allocation function.";
+    context->allocate = oom_killer_cfallocator_malloc;
+
+    context = ContextForCFAllocator(kCFAllocatorMallocZone);
+    CHECK(context) << "Failed to get context for kCFAllocatorMallocZone.";
+    g_old_cfallocator_malloc_zone = context->allocate;
+    CHECK(g_old_cfallocator_malloc_zone)
+        << "Failed to get kCFAllocatorMallocZone allocation function.";
+    context->allocate = oom_killer_cfallocator_malloc_zone;
+  } else {
+    DLOG(WARNING) << "Internals of CFAllocator not known; out-of-memory "
+                     "failures via CFAllocator will not result in termination. "
+                     "http://crbug.com/45650";
+  }
+#endif
+
+  // === Cocoa NSObject allocation ===
+
+  // Note that both +[NSObject new] and +[NSObject alloc] call through to
+  // +[NSObject allocWithZone:].
+
+  CHECK(!g_old_allocWithZone) << "Old allocator unexpectedly non-null";
+
+  Class nsobject_class = [NSObject class];
+  Method orig_method =
+      class_getClassMethod(nsobject_class, @selector(allocWithZone:));
+  g_old_allocWithZone =
+      reinterpret_cast<allocWithZone_t>(method_getImplementation(orig_method));
+  CHECK(g_old_allocWithZone)
+      << "Failed to get allocWithZone allocation function.";
+  method_setImplementation(orig_method,
+                           reinterpret_cast<IMP>(oom_killer_allocWithZone));
+}
+
+}  // namespace allocator
+}  // namespace base
diff --git a/base/debug/stack_trace_posix.cc b/base/debug/stack_trace_posix.cc
index db999b7..da86bdc 100644
--- a/base/debug/stack_trace_posix.cc
+++ b/base/debug/stack_trace_posix.cc
@@ -22,7 +22,7 @@
 #include <string>
 #include <vector>
 
-#if defined(__GLIBCXX__)
+#if !defined(USE_SYMBOLIZE)
 #include <cxxabi.h>
 #endif
 #if !defined(__UCLIBC__)
@@ -58,7 +58,7 @@
 
 volatile sig_atomic_t in_signal_handler = 0;
 
-#if !defined(USE_SYMBOLIZE) && defined(__GLIBCXX__)
+#if !defined(USE_SYMBOLIZE)
 // The prefix used for mangled symbols, per the Itanium C++ ABI:
 // http://www.codesourcery.com/cxx-abi/abi.html#mangling
 const char kMangledSymbolPrefix[] = "_Z";
@@ -67,7 +67,7 @@
 // (('a'..'z').to_a+('A'..'Z').to_a+('0'..'9').to_a + ['_']).join
 const char kSymbolCharacters[] =
     "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
-#endif  // !defined(USE_SYMBOLIZE) && defined(__GLIBCXX__)
+#endif  // !defined(USE_SYMBOLIZE)
 
 #if !defined(USE_SYMBOLIZE)
 // Demangles C++ symbols in the given text. Example:
@@ -79,7 +79,7 @@
   // Note: code in this function is NOT async-signal safe (std::string uses
   // malloc internally).
 
-#if defined(__GLIBCXX__) && !defined(__UCLIBC__)
+#if !defined(__UCLIBC__)
 
   std::string::size_type search_from = 0;
   while (search_from < text->size()) {
@@ -115,8 +115,7 @@
       search_from = mangled_start + 2;
     }
   }
-
-#endif  // defined(__GLIBCXX__) && !defined(__UCLIBC__)
+#endif  // !defined(__UCLIBC__)
 }
 #endif  // !defined(USE_SYMBOLIZE)
 
diff --git a/base/process/memory_mac.mm b/base/process/memory_mac.mm
index 4c1b120..155004dc 100644
--- a/base/process/memory_mac.mm
+++ b/base/process/memory_mac.mm
@@ -4,25 +4,8 @@
 
 #include "base/process/memory.h"
 
-#include <CoreFoundation/CoreFoundation.h>
-#import <Foundation/Foundation.h>
-#include <errno.h>
-#include <mach/mach.h>
-#include <mach/mach_vm.h>
-#include <malloc/malloc.h>
-#import <objc/runtime.h>
-#include <stddef.h>
-
-#include <new>
-
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/mac/mac_util.h"
-#include "base/mac/mach_logging.h"
-#include "base/scoped_clear_errno.h"
+#include "base/allocator/allocator_interception_mac.h"
 #include "build/build_config.h"
-#include "third_party/apple_apsl/CFBase.h"
-#include "third_party/apple_apsl/malloc.h"
 
 namespace base {
 
@@ -32,521 +15,16 @@
 #endif
 }
 
-// ------------------------------------------------------------------------
-
-namespace {
-
-bool g_oom_killer_enabled;
-
-#if !defined(ADDRESS_SANITIZER)
-
-// Starting with Mac OS X 10.7, the zone allocators set up by the system are
-// read-only, to prevent them from being overwritten in an attack. However,
-// blindly unprotecting and reprotecting the zone allocators fails with
-// GuardMalloc because GuardMalloc sets up its zone allocator using a block of
-// memory in its bss. Explicit saving/restoring of the protection is required.
-//
-// This function takes a pointer to a malloc zone, de-protects it if necessary,
-// and returns (in the out parameters) a region of memory (if any) to be
-// re-protected when modifications are complete. This approach assumes that
-// there is no contention for the protection of this memory.
-void DeprotectMallocZone(ChromeMallocZone* default_zone,
-                         mach_vm_address_t* reprotection_start,
-                         mach_vm_size_t* reprotection_length,
-                         vm_prot_t* reprotection_value) {
-  mach_port_t unused;
-  *reprotection_start = reinterpret_cast<mach_vm_address_t>(default_zone);
-  struct vm_region_basic_info_64 info;
-  mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
-  kern_return_t result =
-      mach_vm_region(mach_task_self(),
-                     reprotection_start,
-                     reprotection_length,
-                     VM_REGION_BASIC_INFO_64,
-                     reinterpret_cast<vm_region_info_t>(&info),
-                     &count,
-                     &unused);
-  MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_region";
-
-  // The kernel always returns a null object for VM_REGION_BASIC_INFO_64, but
-  // balance it with a deallocate in case this ever changes. See 10.9.2
-  // xnu-2422.90.20/osfmk/vm/vm_map.c vm_map_region.
-  mach_port_deallocate(mach_task_self(), unused);
-
-  // Does the region fully enclose the zone pointers? Possibly unwarranted
-  // simplification used: using the size of a full version 8 malloc zone rather
-  // than the actual smaller size if the passed-in zone is not version 8.
-  CHECK(*reprotection_start <=
-            reinterpret_cast<mach_vm_address_t>(default_zone));
-  mach_vm_size_t zone_offset = reinterpret_cast<mach_vm_size_t>(default_zone) -
-      reinterpret_cast<mach_vm_size_t>(*reprotection_start);
-  CHECK(zone_offset + sizeof(ChromeMallocZone) <= *reprotection_length);
-
-  if (info.protection & VM_PROT_WRITE) {
-    // No change needed; the zone is already writable.
-    *reprotection_start = 0;
-    *reprotection_length = 0;
-    *reprotection_value = VM_PROT_NONE;
-  } else {
-    *reprotection_value = info.protection;
-    result = mach_vm_protect(mach_task_self(),
-                             *reprotection_start,
-                             *reprotection_length,
-                             false,
-                             info.protection | VM_PROT_WRITE);
-    MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect";
-  }
-}
-
-// === C malloc/calloc/valloc/realloc/posix_memalign ===
-
-typedef void* (*malloc_type)(struct _malloc_zone_t* zone,
-                             size_t size);
-typedef void* (*calloc_type)(struct _malloc_zone_t* zone,
-                             size_t num_items,
-                             size_t size);
-typedef void* (*valloc_type)(struct _malloc_zone_t* zone,
-                             size_t size);
-typedef void (*free_type)(struct _malloc_zone_t* zone,
-                          void* ptr);
-typedef void* (*realloc_type)(struct _malloc_zone_t* zone,
-                              void* ptr,
-                              size_t size);
-typedef void* (*memalign_type)(struct _malloc_zone_t* zone,
-                               size_t alignment,
-                               size_t size);
-
-malloc_type g_old_malloc;
-calloc_type g_old_calloc;
-valloc_type g_old_valloc;
-free_type g_old_free;
-realloc_type g_old_realloc;
-memalign_type g_old_memalign;
-
-malloc_type g_old_malloc_purgeable;
-calloc_type g_old_calloc_purgeable;
-valloc_type g_old_valloc_purgeable;
-free_type g_old_free_purgeable;
-realloc_type g_old_realloc_purgeable;
-memalign_type g_old_memalign_purgeable;
-
-void* oom_killer_malloc(struct _malloc_zone_t* zone,
-                        size_t size) {
-  void* result = g_old_malloc(zone, size);
-  if (!result && size)
-    TerminateBecauseOutOfMemory(size);
-  return result;
-}
-
-void* oom_killer_calloc(struct _malloc_zone_t* zone,
-                        size_t num_items,
-                        size_t size) {
-  void* result = g_old_calloc(zone, num_items, size);
-  if (!result && num_items && size)
-    TerminateBecauseOutOfMemory(num_items * size);
-  return result;
-}
-
-void* oom_killer_valloc(struct _malloc_zone_t* zone,
-                        size_t size) {
-  void* result = g_old_valloc(zone, size);
-  if (!result && size)
-    TerminateBecauseOutOfMemory(size);
-  return result;
-}
-
-void oom_killer_free(struct _malloc_zone_t* zone,
-                     void* ptr) {
-  g_old_free(zone, ptr);
-}
-
-void* oom_killer_realloc(struct _malloc_zone_t* zone,
-                         void* ptr,
-                         size_t size) {
-  void* result = g_old_realloc(zone, ptr, size);
-  if (!result && size)
-    TerminateBecauseOutOfMemory(size);
-  return result;
-}
-
-void* oom_killer_memalign(struct _malloc_zone_t* zone,
-                          size_t alignment,
-                          size_t size) {
-  void* result = g_old_memalign(zone, alignment, size);
-  // Only die if posix_memalign would have returned ENOMEM, since there are
-  // other reasons why NULL might be returned (see
-  // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ).
-  if (!result && size && alignment >= sizeof(void*) &&
-      (alignment & (alignment - 1)) == 0) {
-    TerminateBecauseOutOfMemory(size);
-  }
-  return result;
-}
-
-void* oom_killer_malloc_purgeable(struct _malloc_zone_t* zone,
-                                  size_t size) {
-  void* result = g_old_malloc_purgeable(zone, size);
-  if (!result && size)
-    TerminateBecauseOutOfMemory(size);
-  return result;
-}
-
-void* oom_killer_calloc_purgeable(struct _malloc_zone_t* zone,
-                                  size_t num_items,
-                                  size_t size) {
-  void* result = g_old_calloc_purgeable(zone, num_items, size);
-  if (!result && num_items && size)
-    TerminateBecauseOutOfMemory(num_items * size);
-  return result;
-}
-
-void* oom_killer_valloc_purgeable(struct _malloc_zone_t* zone,
-                                  size_t size) {
-  void* result = g_old_valloc_purgeable(zone, size);
-  if (!result && size)
-    TerminateBecauseOutOfMemory(size);
-  return result;
-}
-
-void oom_killer_free_purgeable(struct _malloc_zone_t* zone,
-                               void* ptr) {
-  g_old_free_purgeable(zone, ptr);
-}
-
-void* oom_killer_realloc_purgeable(struct _malloc_zone_t* zone,
-                                   void* ptr,
-                                   size_t size) {
-  void* result = g_old_realloc_purgeable(zone, ptr, size);
-  if (!result && size)
-    TerminateBecauseOutOfMemory(size);
-  return result;
-}
-
-void* oom_killer_memalign_purgeable(struct _malloc_zone_t* zone,
-                                    size_t alignment,
-                                    size_t size) {
-  void* result = g_old_memalign_purgeable(zone, alignment, size);
-  // Only die if posix_memalign would have returned ENOMEM, since there are
-  // other reasons why NULL might be returned (see
-  // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c ).
-  if (!result && size && alignment >= sizeof(void*)
-      && (alignment & (alignment - 1)) == 0) {
-    TerminateBecauseOutOfMemory(size);
-  }
-  return result;
-}
-
-#endif  // !defined(ADDRESS_SANITIZER)
-
-// === C++ operator new ===
-
-void oom_killer_new() {
-  TerminateBecauseOutOfMemory(0);
-}
-
-#if !defined(ADDRESS_SANITIZER)
-
-// === Core Foundation CFAllocators ===
-
-bool CanGetContextForCFAllocator() {
-  return !base::mac::IsOSLaterThan10_12_DontCallThis();
-}
-
-CFAllocatorContext* ContextForCFAllocator(CFAllocatorRef allocator) {
-  ChromeCFAllocatorLions* our_allocator =
-      const_cast<ChromeCFAllocatorLions*>(
-          reinterpret_cast<const ChromeCFAllocatorLions*>(allocator));
-  return &our_allocator->_context;
-}
-
-CFAllocatorAllocateCallBack g_old_cfallocator_system_default;
-CFAllocatorAllocateCallBack g_old_cfallocator_malloc;
-CFAllocatorAllocateCallBack g_old_cfallocator_malloc_zone;
-
-void* oom_killer_cfallocator_system_default(CFIndex alloc_size,
-                                            CFOptionFlags hint,
-                                            void* info) {
-  void* result = g_old_cfallocator_system_default(alloc_size, hint, info);
-  if (!result)
-    TerminateBecauseOutOfMemory(alloc_size);
-  return result;
-}
-
-void* oom_killer_cfallocator_malloc(CFIndex alloc_size,
-                                    CFOptionFlags hint,
-                                    void* info) {
-  void* result = g_old_cfallocator_malloc(alloc_size, hint, info);
-  if (!result)
-    TerminateBecauseOutOfMemory(alloc_size);
-  return result;
-}
-
-void* oom_killer_cfallocator_malloc_zone(CFIndex alloc_size,
-                                         CFOptionFlags hint,
-                                         void* info) {
-  void* result = g_old_cfallocator_malloc_zone(alloc_size, hint, info);
-  if (!result)
-    TerminateBecauseOutOfMemory(alloc_size);
-  return result;
-}
-
-#endif  // !defined(ADDRESS_SANITIZER)
-
-// === Cocoa NSObject allocation ===
-
-typedef id (*allocWithZone_t)(id, SEL, NSZone*);
-allocWithZone_t g_old_allocWithZone;
-
-id oom_killer_allocWithZone(id self, SEL _cmd, NSZone* zone)
-{
-  id result = g_old_allocWithZone(self, _cmd, zone);
-  if (!result)
-    TerminateBecauseOutOfMemory(0);
-  return result;
-}
-
-}  // namespace
-
 bool UncheckedMalloc(size_t size, void** result) {
-#if defined(ADDRESS_SANITIZER)
-  *result = malloc(size);
-#else
-  if (g_old_malloc) {
-    *result = g_old_malloc(malloc_default_zone(), size);
-  } else {
-    *result = malloc(size);
-  }
-#endif  // defined(ADDRESS_SANITIZER)
-
-  return *result != NULL;
+  return allocator::UncheckedMallocMac(size, result);
 }
 
 bool UncheckedCalloc(size_t num_items, size_t size, void** result) {
-#if defined(ADDRESS_SANITIZER)
-  *result = calloc(num_items, size);
-#else
-  if (g_old_calloc) {
-    *result = g_old_calloc(malloc_default_zone(), num_items, size);
-  } else {
-    *result = calloc(num_items, size);
-  }
-#endif  // defined(ADDRESS_SANITIZER)
-
-  return *result != NULL;
-}
-
-void* UncheckedMalloc(size_t size) {
-  void* address;
-  return UncheckedMalloc(size, &address) ? address : NULL;
-}
-
-void* UncheckedCalloc(size_t num_items, size_t size) {
-  void* address;
-  return UncheckedCalloc(num_items, size, &address) ? address : NULL;
+  return allocator::UncheckedCallocMac(num_items, size, result);
 }
 
 void EnableTerminationOnOutOfMemory() {
-  if (g_oom_killer_enabled)
-    return;
-
-  g_oom_killer_enabled = true;
-
-  // === C malloc/calloc/valloc/realloc/posix_memalign ===
-
-  // This approach is not perfect, as requests for amounts of memory larger than
-  // MALLOC_ABSOLUTE_MAX_SIZE (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will
-  // still fail with a NULL rather than dying (see
-  // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c for details).
-  // Unfortunately, it's the best we can do. Also note that this does not affect
-  // allocations from non-default zones.
-
-#if !defined(ADDRESS_SANITIZER)
-  // Don't do anything special on OOM for the malloc zones replaced by
-  // AddressSanitizer, as modifying or protecting them may not work correctly.
-
-  CHECK(!g_old_malloc && !g_old_calloc && !g_old_valloc && !g_old_realloc &&
-        !g_old_memalign) << "Old allocators unexpectedly non-null";
-
-  CHECK(!g_old_malloc_purgeable && !g_old_calloc_purgeable &&
-        !g_old_valloc_purgeable && !g_old_realloc_purgeable &&
-        !g_old_memalign_purgeable) << "Old allocators unexpectedly non-null";
-
-  ChromeMallocZone* default_zone =
-      reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
-  ChromeMallocZone* purgeable_zone =
-      reinterpret_cast<ChromeMallocZone*>(malloc_default_purgeable_zone());
-
-  mach_vm_address_t default_reprotection_start = 0;
-  mach_vm_size_t default_reprotection_length = 0;
-  vm_prot_t default_reprotection_value = VM_PROT_NONE;
-  DeprotectMallocZone(default_zone,
-                      &default_reprotection_start,
-                      &default_reprotection_length,
-                      &default_reprotection_value);
-
-  mach_vm_address_t purgeable_reprotection_start = 0;
-  mach_vm_size_t purgeable_reprotection_length = 0;
-  vm_prot_t purgeable_reprotection_value = VM_PROT_NONE;
-  if (purgeable_zone) {
-    DeprotectMallocZone(purgeable_zone,
-                        &purgeable_reprotection_start,
-                        &purgeable_reprotection_length,
-                        &purgeable_reprotection_value);
-  }
-
-  // Default zone
-
-  g_old_malloc = default_zone->malloc;
-  g_old_calloc = default_zone->calloc;
-  g_old_valloc = default_zone->valloc;
-  g_old_free = default_zone->free;
-  g_old_realloc = default_zone->realloc;
-  CHECK(g_old_malloc && g_old_calloc && g_old_valloc && g_old_free &&
-        g_old_realloc)
-      << "Failed to get system allocation functions.";
-
-  default_zone->malloc = oom_killer_malloc;
-  default_zone->calloc = oom_killer_calloc;
-  default_zone->valloc = oom_killer_valloc;
-  default_zone->free = oom_killer_free;
-  default_zone->realloc = oom_killer_realloc;
-
-  if (default_zone->version >= 5) {
-    g_old_memalign = default_zone->memalign;
-    if (g_old_memalign)
-      default_zone->memalign = oom_killer_memalign;
-  }
-
-  // Purgeable zone (if it exists)
-
-  if (purgeable_zone) {
-    g_old_malloc_purgeable = purgeable_zone->malloc;
-    g_old_calloc_purgeable = purgeable_zone->calloc;
-    g_old_valloc_purgeable = purgeable_zone->valloc;
-    g_old_free_purgeable = purgeable_zone->free;
-    g_old_realloc_purgeable = purgeable_zone->realloc;
-    CHECK(g_old_malloc_purgeable && g_old_calloc_purgeable &&
-          g_old_valloc_purgeable && g_old_free_purgeable &&
-          g_old_realloc_purgeable)
-        << "Failed to get system allocation functions.";
-
-    purgeable_zone->malloc = oom_killer_malloc_purgeable;
-    purgeable_zone->calloc = oom_killer_calloc_purgeable;
-    purgeable_zone->valloc = oom_killer_valloc_purgeable;
-    purgeable_zone->free = oom_killer_free_purgeable;
-    purgeable_zone->realloc = oom_killer_realloc_purgeable;
-
-    if (purgeable_zone->version >= 5) {
-      g_old_memalign_purgeable = purgeable_zone->memalign;
-      if (g_old_memalign_purgeable)
-        purgeable_zone->memalign = oom_killer_memalign_purgeable;
-    }
-  }
-
-  // Restore protection if it was active.
-
-  if (default_reprotection_start) {
-    kern_return_t result = mach_vm_protect(mach_task_self(),
-                                           default_reprotection_start,
-                                           default_reprotection_length,
-                                           false,
-                                           default_reprotection_value);
-    MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect";
-  }
-
-  if (purgeable_reprotection_start) {
-    kern_return_t result = mach_vm_protect(mach_task_self(),
-                                           purgeable_reprotection_start,
-                                           purgeable_reprotection_length,
-                                           false,
-                                           purgeable_reprotection_value);
-    MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect";
-  }
-#endif
-
-  // === C malloc_zone_batch_malloc ===
-
-  // batch_malloc is omitted because the default malloc zone's implementation
-  // only supports batch_malloc for "tiny" allocations from the free list. It
-  // will fail for allocations larger than "tiny", and will only allocate as
-  // many blocks as it's able to from the free list. These factors mean that it
-  // can return less than the requested memory even in a non-out-of-memory
-  // situation. There's no good way to detect whether a batch_malloc failure is
-  // due to these other factors, or due to genuine memory or address space
-  // exhaustion. The fact that it only allocates space from the "tiny" free list
-  // means that it's likely that a failure will not be due to memory exhaustion.
-  // Similarly, these constraints on batch_malloc mean that callers must always
-  // be expecting to receive less memory than was requested, even in situations
-  // where memory pressure is not a concern. Finally, the only public interface
-  // to batch_malloc is malloc_zone_batch_malloc, which is specific to the
-  // system's malloc implementation. It's unlikely that anyone's even heard of
-  // it.
-
-  // === C++ operator new ===
-
-  // Yes, operator new does call through to malloc, but this will catch failures
-  // that our imperfect handling of malloc cannot.
-
-  std::set_new_handler(oom_killer_new);
-
-#ifndef ADDRESS_SANITIZER
-  // === Core Foundation CFAllocators ===
-
-  // This will not catch allocation done by custom allocators, but will catch
-  // all allocation done by system-provided ones.
-
-  CHECK(!g_old_cfallocator_system_default && !g_old_cfallocator_malloc &&
-        !g_old_cfallocator_malloc_zone)
-      << "Old allocators unexpectedly non-null";
-
-  bool cf_allocator_internals_known = CanGetContextForCFAllocator();
-
-  if (cf_allocator_internals_known) {
-    CFAllocatorContext* context =
-        ContextForCFAllocator(kCFAllocatorSystemDefault);
-    CHECK(context) << "Failed to get context for kCFAllocatorSystemDefault.";
-    g_old_cfallocator_system_default = context->allocate;
-    CHECK(g_old_cfallocator_system_default)
-        << "Failed to get kCFAllocatorSystemDefault allocation function.";
-    context->allocate = oom_killer_cfallocator_system_default;
-
-    context = ContextForCFAllocator(kCFAllocatorMalloc);
-    CHECK(context) << "Failed to get context for kCFAllocatorMalloc.";
-    g_old_cfallocator_malloc = context->allocate;
-    CHECK(g_old_cfallocator_malloc)
-        << "Failed to get kCFAllocatorMalloc allocation function.";
-    context->allocate = oom_killer_cfallocator_malloc;
-
-    context = ContextForCFAllocator(kCFAllocatorMallocZone);
-    CHECK(context) << "Failed to get context for kCFAllocatorMallocZone.";
-    g_old_cfallocator_malloc_zone = context->allocate;
-    CHECK(g_old_cfallocator_malloc_zone)
-        << "Failed to get kCFAllocatorMallocZone allocation function.";
-    context->allocate = oom_killer_cfallocator_malloc_zone;
-  } else {
-    DLOG(WARNING) << "Internals of CFAllocator not known; out-of-memory "
-                     "failures via CFAllocator will not result in termination. "
-                     "http://crbug.com/45650";
-  }
-#endif
-
-  // === Cocoa NSObject allocation ===
-
-  // Note that both +[NSObject new] and +[NSObject alloc] call through to
-  // +[NSObject allocWithZone:].
-
-  CHECK(!g_old_allocWithZone)
-      << "Old allocator unexpectedly non-null";
-
-  Class nsobject_class = [NSObject class];
-  Method orig_method = class_getClassMethod(nsobject_class,
-                                            @selector(allocWithZone:));
-  g_old_allocWithZone = reinterpret_cast<allocWithZone_t>(
-      method_getImplementation(orig_method));
-  CHECK(g_old_allocWithZone)
-      << "Failed to get allocWithZone allocation function.";
-  method_setImplementation(orig_method,
-                           reinterpret_cast<IMP>(oom_killer_allocWithZone));
+  allocator::InterceptAllocationsMac();
 }
 
 }  // namespace base
diff --git a/build/android/pylib/local/device/local_device_environment.py b/build/android/pylib/local/device/local_device_environment.py
index 2aaf88b..4612231 100644
--- a/build/android/pylib/local/device/local_device_environment.py
+++ b/build/android/pylib/local/device/local_device_environment.py
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import contextlib
 import datetime
 import functools
 import logging
@@ -97,7 +96,8 @@
 
   #override
   def SetUp(self):
-    pass
+    if self.trace_output:
+      self.EnableTracing()
 
   def _InitDevices(self):
     device_arg = 'default'
@@ -197,6 +197,9 @@
 
   #override
   def TearDown(self):
+    if self.trace_output:
+      self.DisableTracing()
+
     if self._devices is None:
       return
     @handle_shard_failures_with(on_failure=self.BlacklistDevice)
@@ -261,11 +264,3 @@
       logging.warning('Tracing is already running.')
     else:
       trace_event.trace_enable(self._trace_output + '.json')
-
-  @contextlib.contextmanager
-  def Tracing(self):
-    try:
-      self.EnableTracing()
-      yield
-    finally:
-      self.DisableTracing()
diff --git a/build/android/pylib/local/device/local_device_gtest_run.py b/build/android/pylib/local/device/local_device_gtest_run.py
index e99c4a55..c361f2f 100644
--- a/build/android/pylib/local/device/local_device_gtest_run.py
+++ b/build/android/pylib/local/device/local_device_gtest_run.py
@@ -266,6 +266,7 @@
   def SetUp(self):
     @local_device_environment.handle_shard_failures_with(
         on_failure=self._env.BlacklistDevice)
+    @trace_event.traced
     def individual_device_set_up(dev, host_device_tuples):
       def install_apk():
         # Install test APK.
@@ -373,35 +374,32 @@
   #override
   def _RunTest(self, device, test):
     # Run the test.
-    with contextlib_ext.Optional(
-        self._env.Tracing(),
-        self._env.trace_output):
-      timeout = (self._test_instance.shard_timeout
-                 * self.GetTool(device).GetTimeoutScale())
-      if self._test_instance.store_tombstones:
-        tombstones.ClearAllTombstones(device)
-      with device_temp_file.DeviceTempFile(
-          adb=device.adb,
-          dir=self._delegate.ResultsDirectory(device),
-          suffix='.xml') as device_tmp_results_file:
+    timeout = (self._test_instance.shard_timeout
+               * self.GetTool(device).GetTimeoutScale())
+    if self._test_instance.store_tombstones:
+      tombstones.ClearAllTombstones(device)
+    with device_temp_file.DeviceTempFile(
+        adb=device.adb,
+        dir=self._delegate.ResultsDirectory(device),
+        suffix='.xml') as device_tmp_results_file:
 
-        flags = self._test_instance.test_arguments or ''
-        if self._test_instance.enable_xml_result_parsing:
-          flags += ' --gtest_output=xml:%s' % device_tmp_results_file.name
-        if self._test_instance.gtest_also_run_disabled_tests:
-          flags += ' --gtest_also_run_disabled_tests'
+      flags = self._test_instance.test_arguments or ''
+      if self._test_instance.enable_xml_result_parsing:
+        flags += ' --gtest_output=xml:%s' % device_tmp_results_file.name
+      if self._test_instance.gtest_also_run_disabled_tests:
+        flags += ' --gtest_also_run_disabled_tests'
 
-        with contextlib_ext.Optional(
-            trace_event.trace(str(test)),
-            self._env.trace_output):
-          output = self._delegate.Run(
-              test, device, flags=flags,
-              timeout=timeout, retries=0)
+      with contextlib_ext.Optional(
+          trace_event.trace(str(test)),
+          self._env.trace_output):
+        output = self._delegate.Run(
+            test, device, flags=flags,
+            timeout=timeout, retries=0)
 
-        if self._test_instance.enable_xml_result_parsing:
-          gtest_xml = device.ReadFile(
-              device_tmp_results_file.name,
-              as_root=True)
+      if self._test_instance.enable_xml_result_parsing:
+        gtest_xml = device.ReadFile(
+            device_tmp_results_file.name,
+            as_root=True)
 
     for s in self._servers[str(device)]:
       s.Reset()
@@ -445,6 +443,7 @@
   #override
   def TearDown(self):
     @local_device_environment.handle_shard_failures
+    @trace_event.traced
     def individual_device_tear_down(dev):
       for s in self._servers.get(str(dev), []):
         s.TearDown()
diff --git a/build/android/pylib/local/device/local_device_instrumentation_test_run.py b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
index 0205b7c0..360a4648 100644
--- a/build/android/pylib/local/device/local_device_instrumentation_test_run.py
+++ b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
@@ -17,6 +17,8 @@
 from pylib.instrumentation import instrumentation_test_instance
 from pylib.local.device import local_device_environment
 from pylib.local.device import local_device_test_run
+from py_trace_event import trace_event
+from py_utils import contextlib_ext
 import tombstones
 
 _TAG = 'test_runner_py'
@@ -68,6 +70,7 @@
   def SetUp(self):
     @local_device_environment.handle_shard_failures_with(
         self._env.BlacklistDevice)
+    @trace_event.traced
     def individual_device_set_up(dev, host_device_tuples):
       def install_apk():
         if self._test_instance.apk_under_test:
@@ -152,6 +155,7 @@
   def TearDown(self):
     @local_device_environment.handle_shard_failures_with(
         self._env.BlacklistDevice)
+    @trace_event.traced
     def individual_device_tear_down(dev):
       if str(dev) in self._flag_changers:
         self._flag_changers[str(dev)].Restore()
@@ -255,12 +259,18 @@
             device.serial)
         with logdog_logcat_monitor.LogdogLogcatMonitor(
             device.adb, stream_name) as logmon:
-          output = device.StartInstrumentation(
-              target, raw=True, extras=extras, timeout=timeout, retries=0)
+          with contextlib_ext.Optional(
+              trace_event.trace(test_name),
+              self._env.trace_output):
+            output = device.StartInstrumentation(
+                target, raw=True, extras=extras, timeout=timeout, retries=0)
         logcat_url = logmon.GetLogcatURL()
       else:
-        output = device.StartInstrumentation(
-            target, raw=True, extras=extras, timeout=timeout, retries=0)
+        with contextlib_ext.Optional(
+            trace_event.trace(test_name),
+            self._env.trace_output):
+          output = device.StartInstrumentation(
+              target, raw=True, extras=extras, timeout=timeout, retries=0)
     finally:
       device.RunShellCommand(
           ['log', '-p', 'i', '-t', _TAG, 'END %s' % test_name],
diff --git a/build/android/pylib/local/device/local_device_perf_test_run.py b/build/android/pylib/local/device/local_device_perf_test_run.py
index 77f1a4e..19e2003 100644
--- a/build/android/pylib/local/device/local_device_perf_test_run.py
+++ b/build/android/pylib/local/device/local_device_perf_test_run.py
@@ -265,6 +265,7 @@
     logging.info('%s : exit_code=%d in %d secs on device %s',
                  test, exit_code, duration, str(self._device))
 
+  @trace_event.traced
   def _TestSetUp(self, test):
     if not self._device.IsOnline():
       msg = 'Device %s is unresponsive.' % str(self._device)
@@ -298,6 +299,7 @@
     persisted_result['host_test'] = False
     persisted_result['device'] = str(self._device)
 
+  @trace_event.traced
   def _TestTearDown(self):
     try:
       logging.info('Unmapping device ports for %s.', self._device)
@@ -455,16 +457,12 @@
           device_shard_helper)
       return [x for x in shards.pGet(self._timeout) if x is not None]
 
-    # Run the tests.
-    with contextlib_ext.Optional(
-        self._env.Tracing(),
-        self._env.trace_output):
-      # Affinitize the tests.
-      self._SplitTestsByAffinity()
-      if not self._test_buckets and not self._no_device_tests:
-        raise local_device_test_run.NoTestsError()
-      host_test_results, device_test_results = reraiser_thread.RunAsync(
-          [run_no_devices_tests, run_devices_tests])
+    # Affinitize the tests.
+    self._SplitTestsByAffinity()
+    if not self._test_buckets and not self._no_device_tests:
+      raise local_device_test_run.NoTestsError()
+    host_test_results, device_test_results = reraiser_thread.RunAsync(
+        [run_no_devices_tests, run_devices_tests])
 
     return host_test_results + device_test_results
 
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index 37d565a..08ec868 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -113,7 +113,8 @@
   group.add_argument('--trace-output', metavar='FILENAME',
                      type=os.path.realpath,
                      help='Path to save test_runner trace data to. This option '
-                          'has been implemented for gtest and perf test.')
+                          'has been implemented for gtest, instrumentation '
+                          'test and perf test.')
 
   logcat_output_group = group.add_mutually_exclusive_group()
   logcat_output_group.add_argument(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
index 508246a8..d71e5e6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
@@ -428,4 +428,30 @@
     public AccountManagerDelegate createAccountManagerDelegate() {
         return new SystemAccountManagerDelegate(this);
     }
+
+    /**
+     * Instantiates an object of a given type.
+     * This method exists as a utility to generate objects of types that have different
+     * implementations upstream and downstream.  To use this,
+     * - give the upstream class a public parameterless constructor (required!)
+     *   e.g., public MyType() {},
+     * - generate the downstream object in createObjectImpl in the ChromeApplication subclass.
+     *   e.g., if (klass.getName().equals(MyType.class.getName()) return (T)new MySubType(), and
+     * - invoke this method on the appropriate class,
+     *   e.g., ChromeApplication.createObject(MyType.class).
+     * @param klass The class that the Chrome Application should create an instance of.
+     */
+    public static <T> T createObject(Class<T> klass) {
+        return ((ChromeApplication) ContextUtils.getApplicationContext()).createObjectImpl(klass);
+    }
+
+    protected <T> T createObjectImpl(Class<T> klass) {
+        try {
+            return klass.newInstance();
+        } catch (InstantiationException e) {
+            throw new RuntimeException("Asked to create unexpected class: " + klass.getName(), e);
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException("Asked to create unexpected class: " + klass.getName(), e);
+        }
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java
index 1c1b9cbf..cf383453 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java
@@ -114,26 +114,19 @@
 
                 MenuItem offlineMenuItem = menu.findItem(R.id.offline_page_id);
                 if (offlineMenuItem != null) {
-                    if (DownloadUtils.isDownloadHomeEnabled()) {
-                        offlineMenuItem.setEnabled(
-                                DownloadUtils.isAllowedToDownloadPage(currentTab));
+                    offlineMenuItem.setEnabled(
+                            DownloadUtils.isAllowedToDownloadPage(currentTab));
 
-                        Drawable drawable = offlineMenuItem.getIcon();
-                        if (drawable != null) {
-                            int iconTint = ApiCompatibilityUtils.getColor(
-                                    mActivity.getResources(), R.color.light_normal_color);
-                            drawable.mutate();
-                            drawable.setColorFilter(iconTint, PorterDuff.Mode.SRC_ATOP);
-                        }
-                    } else {
-                        offlineMenuItem.setVisible(false);
+                    Drawable drawable = offlineMenuItem.getIcon();
+                    if (drawable != null) {
+                        int iconTint = ApiCompatibilityUtils.getColor(
+                                mActivity.getResources(), R.color.light_normal_color);
+                        drawable.mutate();
+                        drawable.setColorFilter(iconTint, PorterDuff.Mode.SRC_ATOP);
                     }
                 }
             }
 
-            menu.findItem(R.id.downloads_menu_id)
-                    .setVisible(DownloadUtils.isDownloadHomeEnabled());
-
             menu.findItem(R.id.update_menu_id).setVisible(
                     UpdateMenuItemHelper.getInstance().shouldShowMenuItem(mActivity));
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java
index 3332351..c4a69187 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java
@@ -120,8 +120,6 @@
      */
     public boolean updateRemoteViews(RemoteViews remoteViews, int[] clickableIDs,
             PendingIntent pendingIntent) {
-        // Update only makes sense if we are already showing a RemoteViews.
-        if (mDataProvider.getBottomBarRemoteViews() == null) return false;
         REMOTE_VIEWS_UPDATED.record();
         if (remoteViews == null) {
             if (mBottomBarView == null) return false;
@@ -132,7 +130,7 @@
             // TODO: investigate updating the RemoteViews without replacing the entire hierarchy.
             mClickableIDs = clickableIDs;
             mClickPendingIntent = pendingIntent;
-            getBottomBarView().removeViewAt(1);
+            if (getBottomBarView().getChildCount() > 1) getBottomBarView().removeViewAt(1);
             showRemoteViews(remoteViews);
         }
         return true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
index b91fa20..abc15768 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -335,6 +335,7 @@
      * @return A array of {@link View} ids, of which the onClick event is handled by the custom tab.
      */
     public int[] getClickableViewIDs() {
+        if (mClickableViewIds == null) return null;
         return mClickableViewIds.clone();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
index 00c85694..d3449c2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -80,6 +80,8 @@
     // Wait 10 seconds to resume all downloads, so that we won't impact tab loading.
     private static final long RESUME_DELAY_MILLIS = 10000;
     private static final int UNKNOWN_DOWNLOAD_STATUS = -1;
+    private static final String PREF_IS_DOWNLOAD_HOME_ENABLED =
+            "org.chromium.chrome.browser.download.IS_DOWNLOAD_HOME_ENABLED";
 
     // Values for the histogram MobileDownloadResumptionCount.
     private static final int UMA_DOWNLOAD_RESUMPTION_MANUAL_PAUSE = 0;
@@ -242,6 +244,8 @@
             long updateDelayInMillis) {
         mContext = context;
         mSharedPrefs = ContextUtils.getAppSharedPreferences();
+        // Clean up unused shared prefs. TODO(qinmin): remove this after M61.
+        mSharedPrefs.edit().remove(PREF_IS_DOWNLOAD_HOME_ENABLED).apply();
         mDownloadNotifier = downloadNotifier;
         mUpdateDelayInMillis = updateDelayInMillis;
         mHandler = handler;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
index 5be9878..d96cf6d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
@@ -9,7 +9,6 @@
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
-import android.content.SharedPreferences;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Color;
@@ -29,7 +28,6 @@
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.UrlConstants;
@@ -78,9 +76,6 @@
     private static final String EXTRA_IS_OFF_THE_RECORD =
             "org.chromium.chrome.browser.download.IS_OFF_THE_RECORD";
 
-    private static final String PREF_IS_DOWNLOAD_HOME_ENABLED =
-            "org.chromium.chrome.browser.download.IS_DOWNLOAD_HOME_ENABLED";
-
     private static final long BYTES_PER_KILOBYTE = 1024;
     private static final long BYTES_PER_MEGABYTE = 1024 * 1024;
     private static final long BYTES_PER_GIGABYTE = 1024 * 1024 * 1024;
@@ -89,30 +84,10 @@
     static final String ELLIPSIS = "\u2026";
 
     /**
-     * @return Whether or not the Download Home is enabled.
-     */
-    public static boolean isDownloadHomeEnabled() {
-        SharedPreferences preferences = ContextUtils.getAppSharedPreferences();
-        return preferences.getBoolean(PREF_IS_DOWNLOAD_HOME_ENABLED, false);
-    }
-
-    /**
-     * Caches the native flag that enables the Download Home in SharedPreferences.
-     * This is necessary because the DownloadActivity can be opened before native has been loaded.
-     */
-    public static void cacheIsDownloadHomeEnabled() {
-        boolean isEnabled = ChromeFeatureList.isEnabled("DownloadsUi");
-        SharedPreferences preferences = ContextUtils.getAppSharedPreferences();
-        preferences.edit().putBoolean(PREF_IS_DOWNLOAD_HOME_ENABLED, isEnabled).apply();
-    }
-
-    /**
      * Displays the download manager UI. Note the UI is different on tablets and on phones.
      * @return Whether the UI was shown.
      */
     public static boolean showDownloadManager(@Nullable Activity activity, @Nullable Tab tab) {
-        if (!isDownloadHomeEnabled()) return false;
-
         // Figure out what tab was last being viewed by the user.
         if (activity == null) activity = ApplicationStatus.getLastTrackedFocusedActivity();
         if (tab == null && activity instanceof ChromeTabbedActivity) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java
index f25b10a..ece6a6d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java
@@ -561,8 +561,7 @@
         if (tab == null) return false;
         // The save offline button should not be shown on native pages. Currently, trying to
         // save an offline page in incognito crashes, so don't show it on incognito either.
-        return DownloadUtils.isDownloadHomeEnabled() && shouldShowPageActionButtons()
-                && !tab.isIncognito();
+        return shouldShowPageActionButtons() && !tab.isIncognito();
     }
 
     private boolean isSaveOfflineButtonEnabled() {
@@ -573,19 +572,15 @@
     private boolean shouldShowPageActionButtons() {
         if (!mNativeInitialized) return true;
 
-        // If the new downloads UI isn't enabled, the only page action is the bookmark button. It
-        // should be shown if the delete button isn't showing. If the download UI is enabled, there
-        // are two actions, bookmark and save offline, and they should be shown if the omnibox isn't
-        // focused.
-        return (!shouldShowDeleteButton() && !DownloadUtils.isDownloadHomeEnabled())
-                || !(mUrlBar.hasFocus() || mUrlFocusChangeInProgress);
+        // There are two actions, bookmark and save offline, and they should be shown if the
+        // omnibox isn't focused.
+        return !(mUrlBar.hasFocus() || mUrlFocusChangeInProgress);
     }
 
     private boolean shouldShowMicButton() {
         // If the download UI is enabled, the mic button should be only be shown when the url bar
         // is focused.
         return isVoiceSearchEnabled() && mNativeInitialized
-                && (!DownloadUtils.isDownloadHomeEnabled()
-                        || (mUrlBar.hasFocus() || mUrlFocusChangeInProgress));
+                && (mUrlBar.hasFocus() || mUrlFocusChangeInProgress);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SuggestionView.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SuggestionView.java
index c7d828d..c5253338 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SuggestionView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SuggestionView.java
@@ -329,7 +329,8 @@
                 mContentsView.mTextLine2.setVisibility(INVISIBLE);
             }
             setSuggestedQuery(suggestionItem, true, urlShown, urlHighlighted);
-            setRefinable(!sameAsTyped);
+            setRefinable(!sameAsTyped
+                    && suggestionType != OmniboxSuggestionType.PHYSICAL_WEB_OVERFLOW);
         } else {
             @SuggestionIcon int suggestionIcon = SUGGESTION_ICON_MAGNIFIER;
             if (suggestionType == OmniboxSuggestionType.VOICE_SUGGEST) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentPreferencesUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentPreferencesUtil.java
index 62e40a3..5fcecc3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentPreferencesUtil.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentPreferencesUtil.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.payments;
 
 import org.chromium.base.ContextUtils;
+import org.chromium.base.VisibleForTesting;
 
 /** Place to define and control payment preferences. */
 public class PaymentPreferencesUtil {
@@ -17,6 +18,12 @@
     /** Prefix of the preferences to persist Android payment apps' status. */
     public static final String PAYMENT_ANDROID_APP_ENABLED_ = "payment_android_app_enabled_";
 
+    /** Prefix of the preferences to persist use count of the payment instruments. */
+    public static final String PAYMENT_INSTRUMENT_USE_COUNT_ = "payment_instrument_use_count_";
+
+    /** Prefix of the preferences to persist last use date of the payment instruments. */
+    public static final String PAYMENT_INSTRUMENT_USE_DATE_ = "payment_instrument_use_date_";
+
     /**
      * Checks whehter the payment request has been successfully completed once.
      *
@@ -55,4 +62,65 @@
     public static String getAndroidPaymentAppEnabledPreferenceKey(String packageName) {
         return PAYMENT_ANDROID_APP_ENABLED_ + packageName;
     }
+
+    /**
+     * Gets use count of the payment instrument.
+     *
+     * @param id The instrument identifier.
+     * @return The use count.
+     */
+    public static int getPaymentInstrumentUseCount(String id) {
+        return ContextUtils.getAppSharedPreferences().getInt(PAYMENT_INSTRUMENT_USE_COUNT_ + id, 0);
+    }
+
+    /**
+     * Increase use count of the payment instrument by one.
+     *
+     * @param id The instrument identifier.
+     */
+    public static void increasePaymentInstrumentUseCount(String id) {
+        ContextUtils.getAppSharedPreferences()
+                .edit()
+                .putInt(PAYMENT_INSTRUMENT_USE_COUNT_ + id, getPaymentInstrumentUseCount(id) + 1)
+                .apply();
+    }
+
+    /**
+     * A convenient method to set use count of the payment instrument to a specific value for test.
+     *
+     * @param id    The instrument identifier.
+     * @param count The count value.
+     */
+    @VisibleForTesting
+    public static void setPaymentInstrumentUseCountForTest(String id, int count) {
+        ContextUtils.getAppSharedPreferences()
+                .edit()
+                .putInt(PAYMENT_INSTRUMENT_USE_COUNT_ + id, count)
+                .apply();
+    }
+
+    /**
+     * Gets last use date of the payment instrument.
+     *
+     * @param id The instrument identifier.
+     * @return The time difference between the last use date and 'midnight, January 1, 1970 UTC' in
+     *         millieseconds.
+     */
+    public static long getPaymentInstrumentLastUseDate(String id) {
+        return ContextUtils.getAppSharedPreferences().getLong(PAYMENT_INSTRUMENT_USE_DATE_ + id, 0);
+    }
+
+    /**
+     * Sets last use date of the payment instrument.
+     *
+     * @param id   The instrument identifier.
+     * @param date The time difference between the last use date and 'midnight, January 1, 1970 UTC'
+     *             in millieseconds.
+     */
+    public static void setPaymentInstrumentLastUseDate(String id, long date) {
+        ContextUtils.getAppSharedPreferences()
+                .edit()
+                .putLong(PAYMENT_INSTRUMENT_USE_DATE_ + id, date)
+                .apply();
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
index bbf43d89..2347e25b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -175,6 +175,27 @@
                 }
             };
 
+    /**
+     * Comparator to sort payment apps by maximum frecency score of the contained instruments. Note
+     * that the first instrument in the list must have the maximum frecency score.
+     */
+    private static final Comparator<List<PaymentInstrument>> APP_FRECENCY_COMPARATOR =
+            new Comparator<List<PaymentInstrument>>() {
+                @Override
+                public int compare(List<PaymentInstrument> a, List<PaymentInstrument> b) {
+                    return compareInstrumentsByFrecency(b.get(0), a.get(0));
+                }
+            };
+
+    /** Comparator to sort instruments in payment apps by frecency. */
+    private static final Comparator<PaymentInstrument> INSTRUMENT_FRECENCY_COMPARATOR =
+            new Comparator<PaymentInstrument>() {
+                @Override
+                public int compare(PaymentInstrument a, PaymentInstrument b) {
+                    return compareInstrumentsByFrecency(b, a);
+                }
+            };
+
     /** Every origin can call canMakePayment() every 30 minutes. */
     private static final int CAN_MAKE_PAYMENT_QUERY_PERIOD_MS = 30 * 60 * 1000;
 
@@ -256,7 +277,7 @@
     private ContactDetailsSection mContactSection;
     private List<PaymentApp> mApps;
     private List<PaymentApp> mPendingApps;
-    private List<PaymentInstrument> mPendingInstruments;
+    private List<List<PaymentInstrument>> mPendingInstruments;
     private List<PaymentInstrument> mPendingAutofillInstruments;
     private SectionInformation mPaymentMethodsSection;
     private PaymentRequestUI mUI;
@@ -1137,6 +1158,17 @@
         if (!PaymentPreferencesUtil.isPaymentCompleteOnce()) {
             PaymentPreferencesUtil.setPaymentCompleteOnce();
         }
+
+        /**
+         * Update records of the used payment instrument for sorting payment apps and instruments
+         * next time.
+         */
+        PaymentOption selectedPaymentMethod = mPaymentMethodsSection.getSelectedItem();
+        PaymentPreferencesUtil.increasePaymentInstrumentUseCount(
+                selectedPaymentMethod.getIdentifier());
+        PaymentPreferencesUtil.setPaymentInstrumentLastUseDate(
+                selectedPaymentMethod.getIdentifier(), System.currentTimeMillis());
+
         closeUI(PaymentComplete.FAIL != result);
     }
 
@@ -1230,17 +1262,26 @@
         // Place the instruments into either "autofill" or "non-autofill" list to be displayed when
         // all apps have responded.
         if (instruments != null) {
+            List<PaymentInstrument> nonAutofillInstruments = new ArrayList<>();
             for (int i = 0; i < instruments.size(); i++) {
                 PaymentInstrument instrument = instruments.get(i);
                 Set<String> instrumentMethodNames = new HashSet<>(
                         instrument.getInstrumentMethodNames());
                 instrumentMethodNames.retainAll(mMethodData.keySet());
                 if (!instrumentMethodNames.isEmpty()) {
-                    addPendingInstrument(instrument);
+                    if (instrument instanceof AutofillPaymentInstrument) {
+                        mPendingAutofillInstruments.add(instrument);
+                    } else {
+                        nonAutofillInstruments.add(instrument);
+                    }
                 } else {
                     instrument.dismissInstrument();
                 }
             }
+            if (!nonAutofillInstruments.isEmpty()) {
+                Collections.sort(nonAutofillInstruments, INSTRUMENT_FRECENCY_COMPARATOR);
+                mPendingInstruments.add(nonAutofillInstruments);
+            }
         }
 
         // Some payment apps still have not responded. Continue waiting for them.
@@ -1272,18 +1313,19 @@
         // > Complete autofill instruments.
         // > Incomplete autofill instruments.
         Collections.sort(mPendingAutofillInstruments, COMPLETENESS_COMPARATOR);
-        mPendingInstruments.addAll(mPendingAutofillInstruments);
+        Collections.sort(mPendingInstruments, APP_FRECENCY_COMPARATOR);
+        if (!mPendingAutofillInstruments.isEmpty()) {
+            mPendingInstruments.add(mPendingAutofillInstruments);
+        }
 
         // Log the number of suggested credit cards.
         mJourneyLogger.setNumberOfSuggestionsShown(PaymentRequestJourneyLogger.SECTION_CREDIT_CARDS,
                 mPendingAutofillInstruments.size());
 
-        mPendingAutofillInstruments.clear();
-
         // Possibly pre-select the first instrument on the list.
         int selection = SectionInformation.NO_SELECTION;
         if (!mPendingInstruments.isEmpty()) {
-            PaymentInstrument first = mPendingInstruments.get(0);
+            PaymentInstrument first = mPendingInstruments.get(0).get(0);
             if (first instanceof AutofillPaymentInstrument) {
                 AutofillPaymentInstrument creditCard = (AutofillPaymentInstrument) first;
                 if (creditCard.isComplete()) selection = 0;
@@ -1298,8 +1340,12 @@
         if (query != null) query.setResponse(mCanMakePayment);
 
         // The list of payment instruments is ready to display.
-        mPaymentMethodsSection = new SectionInformation(PaymentRequestUI.TYPE_PAYMENT_METHODS,
-                selection, mPendingInstruments);
+        List<PaymentInstrument> sortedInstruments = new ArrayList<>();
+        for (List<PaymentInstrument> a : mPendingInstruments) {
+            sortedInstruments.addAll(a);
+        }
+        mPaymentMethodsSection = new SectionInformation(
+                PaymentRequestUI.TYPE_PAYMENT_METHODS, selection, sortedInstruments);
 
         mPendingInstruments.clear();
 
@@ -1347,20 +1393,6 @@
     }
 
     /**
-     * Saves the given instrument in either "autofill" or "non-autofill" list. The separation
-     * enables placing autofill instruments on the bottom of the list.
-     *
-     * @param instrument The instrument to add to either "autofill" or "non-autofill" list.
-     */
-    private void addPendingInstrument(PaymentInstrument instrument) {
-        if (instrument instanceof AutofillPaymentInstrument) {
-            mPendingAutofillInstruments.add(instrument);
-        } else {
-            mPendingInstruments.add(instrument);
-        }
-    }
-
-    /**
      * Called after retrieving instrument details.
      */
     @Override
@@ -1523,4 +1555,28 @@
             mJourneyLogger.recordJourneyStatsHistograms("OtherAborted");
         }
     }
+
+    /**
+     * Compares two payment instruments by frecency.
+     * Return negative value if a has strictly lower frecency score than b.
+     * Return zero if a and b have the same frecency score.
+     * Return positive value if a has strictly higher frecency score than b.
+     */
+    private static int compareInstrumentsByFrecency(PaymentInstrument a, PaymentInstrument b) {
+        int aCount = PaymentPreferencesUtil.getPaymentInstrumentUseCount(a.getIdentifier());
+        int bCount = PaymentPreferencesUtil.getPaymentInstrumentUseCount(b.getIdentifier());
+        long aDate = PaymentPreferencesUtil.getPaymentInstrumentLastUseDate(a.getIdentifier());
+        long bDate = PaymentPreferencesUtil.getPaymentInstrumentLastUseDate(a.getIdentifier());
+
+        return Double.compare(getFrecencyScore(aCount, aDate), getFrecencyScore(bCount, bDate));
+    }
+
+    /**
+     * The frecency score is calculated according to use count and last use date. The formula is
+     * the same as the one used in GetFrecencyScore in autofill_data_model.cc.
+     */
+    private static final double getFrecencyScore(int count, long date) {
+        long currentTime = System.currentTimeMillis();
+        return -Math.log((currentTime - date) / (24 * 60 * 60 * 1000) + 2) / Math.log(count + 2);
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegateImpl.java
index 4db9f8b..4a6b0e36 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegateImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsNavigationDelegateImpl.java
@@ -75,8 +75,6 @@
 
     @Override
     public void navigateToDownloadManager() {
-        assert DownloadUtils.isDownloadHomeEnabled();
-
         RecordUserAction.record("MobileNTPSwitchToDownloadManager");
         DownloadUtils.showDownloadManager(mActivity, mTab);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
index 88a22fb..d625557 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
@@ -26,7 +26,6 @@
 import org.chromium.chrome.browser.ApplicationLifetime;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.download.DownloadUtils;
 import org.chromium.chrome.browser.firstrun.FirstRunGlueImpl;
 import org.chromium.chrome.browser.instantapps.InstantAppsHandler;
 import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
@@ -188,7 +187,6 @@
      */
     public static void cacheNativeFlags() {
         cacheHerbFlavor();
-        DownloadUtils.cacheIsDownloadHomeEnabled();
         InstantAppsHandler.getInstance().cacheInstantAppsEnabled();
         ChromeWebApkHost.cacheEnabledStateForNextLaunch();
         cacheChromeHomeEnabled();
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index 6d2105e..fbb6eb9 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1393,6 +1393,7 @@
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameAndFreeShippingTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java",
+  "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppsSortingTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppCanMakePaymentQueryTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppAndCardsTest.java",
   "javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppAndCardsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppAndCardsTest.java
index 996a69e..774e844 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppAndCardsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppAndCardsTest.java
@@ -129,10 +129,10 @@
         assertEquals(
                 instrumentPresence == HAVE_INSTRUMENTS ? 3 : 2, getNumberOfPaymentInstruments());
 
-        // Check the labesl of the instruments.
+        // Check the labels of the instruments.
         int i = 0;
         if (instrumentPresence == HAVE_INSTRUMENTS) {
-            assertEquals("Test Pay", getPaymentInstrumentLabel(i++));
+            assertEquals("https://bobpay.com", getPaymentInstrumentLabel(i++));
         }
         // \u0020\...\u2006 is four dots ellipsis.
         assertEquals(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppsSortingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppsSortingTest.java
new file mode 100644
index 0000000..226f2fc0
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppsSortingTest.java
@@ -0,0 +1,126 @@
+// Copyright 2017 The Chromium 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.payments;
+
+import static java.util.Arrays.asList;
+
+import android.support.test.filters.MediumTest;
+
+import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.autofill.AutofillTestHelper;
+import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
+import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard;
+
+import java.util.ArrayList;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+/** A payment integration test that sorting payment apps and instruments by frecency. */
+public class PaymentRequestPaymentAppsSortingTest extends PaymentRequestTestBase {
+    public PaymentRequestPaymentAppsSortingTest() {
+        super("payment_request_alicepay_bobpay_charliepay_and_cards_test.html");
+    }
+
+    @Override
+    public void onMainActivityStarted()
+            throws InterruptedException, ExecutionException, TimeoutException {
+        AutofillTestHelper helper = new AutofillTestHelper();
+        String billingAddressId = helper.setProfile(new AutofillProfile("", "https://example.com",
+                true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "",
+                "US", "310-310-6000", "jon.doe@gmail.com", "en-US"));
+        // Visa card with complete set of information. This payment method is always listed
+        // behind non-autofill payment instruments in payment request.
+        helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe",
+                "4111111111111111", "", "12", "2050", "visa", R.drawable.pr_visa, billingAddressId,
+                "" /* serverId */));
+    }
+
+    @MediumTest
+    @Feature({"Payments"})
+    public void testPaymentAppsSortingByFrecency()
+            throws InterruptedException, ExecutionException, TimeoutException {
+        // Install a payment app with Bob Pay and Alice Pay, and another payment app with Charlie
+        // Pay.
+        TestPay appA = installPaymentApp(
+                new ArrayList<String>(asList("https://alicepay.com", "https://bobpay.com")),
+                HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE, IMMEDIATE_CREATION);
+        TestPay appB =
+                installPaymentApp("https://charliepay.com", HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE);
+        String appAAlicePayId = appA.getAppIdentifier() + "https://alicepay.com";
+        String appABobPayId = appA.getAppIdentifier() + "https://bobpay.com";
+        String appBCharliePayId = appB.getAppIdentifier() + "https://charliepay.com";
+
+        // The initial records for all payment methods are zeroes.
+        assertEquals(0, PaymentPreferencesUtil.getPaymentInstrumentUseCount(appAAlicePayId));
+        assertEquals(0, PaymentPreferencesUtil.getPaymentInstrumentUseCount(appABobPayId));
+        assertEquals(0, PaymentPreferencesUtil.getPaymentInstrumentUseCount(appBCharliePayId));
+        assertEquals(0, PaymentPreferencesUtil.getPaymentInstrumentLastUseDate(appAAlicePayId));
+        assertEquals(0, PaymentPreferencesUtil.getPaymentInstrumentLastUseDate(appABobPayId));
+        assertEquals(0, PaymentPreferencesUtil.getPaymentInstrumentLastUseDate(appBCharliePayId));
+
+        // Sets Alice Pay use count and use date to 5. Sets Bob Pay use count and use date to 10.
+        // Sets Charlie Pay use count and use date to 15.
+        PaymentPreferencesUtil.setPaymentInstrumentUseCountForTest(appAAlicePayId, 5);
+        PaymentPreferencesUtil.setPaymentInstrumentLastUseDate(appAAlicePayId, 5);
+        PaymentPreferencesUtil.setPaymentInstrumentUseCountForTest(appABobPayId, 10);
+        PaymentPreferencesUtil.setPaymentInstrumentLastUseDate(appABobPayId, 10);
+        PaymentPreferencesUtil.setPaymentInstrumentUseCountForTest(appBCharliePayId, 15);
+        PaymentPreferencesUtil.setPaymentInstrumentLastUseDate(appBCharliePayId, 15);
+
+        triggerUIAndWait(mReadyToPay);
+        clickInPaymentMethodAndWait(R.id.payments_section, mReadyForInput);
+
+        // Checks Charlie Pay is listed at the first position.
+        assertEquals(4, getNumberOfPaymentInstruments());
+        assertEquals("https://charliepay.com", getPaymentInstrumentLabel(0));
+        assertEquals("https://bobpay.com", getPaymentInstrumentLabel(1));
+        assertEquals("https://alicepay.com", getPaymentInstrumentLabel(2));
+        assertEquals(
+                "Visa\u0020\u0020\u2022\u2006\u2022\u2006\u2022\u2006\u2022\u20061111\nJon Doe",
+                getPaymentInstrumentLabel(3));
+
+        // Cancel the Payment Request.
+        clickAndWait(R.id.button_secondary, mDismissed);
+
+        // Checks the records for all payment instruments haven't been changed.
+        assertEquals(5, PaymentPreferencesUtil.getPaymentInstrumentUseCount(appAAlicePayId));
+        assertEquals(10, PaymentPreferencesUtil.getPaymentInstrumentUseCount(appABobPayId));
+        assertEquals(15, PaymentPreferencesUtil.getPaymentInstrumentUseCount(appBCharliePayId));
+        assertEquals(5, PaymentPreferencesUtil.getPaymentInstrumentLastUseDate(appAAlicePayId));
+        assertEquals(10, PaymentPreferencesUtil.getPaymentInstrumentLastUseDate(appABobPayId));
+        assertEquals(15, PaymentPreferencesUtil.getPaymentInstrumentLastUseDate(appBCharliePayId));
+
+        // Sets Alice Pay use count and use date to 20.
+        PaymentPreferencesUtil.setPaymentInstrumentUseCountForTest(appAAlicePayId, 20);
+        PaymentPreferencesUtil.setPaymentInstrumentLastUseDate(appAAlicePayId, 20);
+
+        reTriggerUIAndWait("buy", mReadyToPay);
+        clickInPaymentMethodAndWait(R.id.payments_section, mReadyForInput);
+
+        // Checks Alice Pay is listed at the first position. Checks Bob Pay is listed at the second
+        // position together with Alice Pay since they come from the same app.
+        assertEquals(4, getNumberOfPaymentInstruments());
+        assertEquals("https://alicepay.com", getPaymentInstrumentLabel(0));
+        assertEquals("https://bobpay.com", getPaymentInstrumentLabel(1));
+        assertEquals("https://charliepay.com", getPaymentInstrumentLabel(2));
+        assertEquals(
+                "Visa\u0020\u0020\u2022\u2006\u2022\u2006\u2022\u2006\u2022\u20061111\nJon Doe",
+                getPaymentInstrumentLabel(3));
+
+        clickAndWait(R.id.button_primary, mDismissed);
+        // Checks Alice Pay is selected as the default payment method.
+        expectResultContains(new String[] {"https://alicepay.com", "\"transaction\"", "1337"});
+
+        // Checks Alice Pay use count is increased by one after completing a payment request with
+        // it.
+        assertEquals(21, PaymentPreferencesUtil.getPaymentInstrumentUseCount(appAAlicePayId));
+        assertEquals(10, PaymentPreferencesUtil.getPaymentInstrumentUseCount(appABobPayId));
+        assertEquals(15, PaymentPreferencesUtil.getPaymentInstrumentUseCount(appBCharliePayId));
+        assertTrue(PaymentPreferencesUtil.getPaymentInstrumentLastUseDate(appAAlicePayId) > 20);
+        assertEquals(10, PaymentPreferencesUtil.getPaymentInstrumentLastUseDate(appABobPayId));
+        assertEquals(15, PaymentPreferencesUtil.getPaymentInstrumentLastUseDate(appBCharliePayId));
+    }
+}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestBase.java
index 3bb2242..5bfd136 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestBase.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestBase.java
@@ -4,6 +4,8 @@
 
 package org.chromium.chrome.browser.payments;
 
+import static java.util.Arrays.asList;
+
 import android.content.Context;
 import android.os.Handler;
 import android.view.View;
@@ -854,7 +856,13 @@
      */
     protected TestPay installPaymentApp(final String methodName, final int instrumentPresence,
             final int responseSpeed, final int creationSpeed) {
-        final TestPay app = new TestPay(methodName, instrumentPresence, responseSpeed);
+        return installPaymentApp(new ArrayList<String>(asList(methodName)), instrumentPresence,
+                responseSpeed, creationSpeed);
+    }
+
+    protected TestPay installPaymentApp(final List<String> methodNames,
+            final int instrumentPresence, final int responseSpeed, final int creationSpeed) {
+        final TestPay app = new TestPay(methodNames, instrumentPresence, responseSpeed);
         PaymentAppFactory.getInstance().addAdditionalFactory(new PaymentAppFactoryAddition() {
             @Override
             public void create(Context context, WebContents webContents, Set<String> methodNames,
@@ -878,13 +886,13 @@
 
     /** A payment app implementation for test. */
     protected static class TestPay implements PaymentApp {
-        private final String mMethodName;
+        private final List<String> mMethodNames;
         private final int mInstrumentPresence;
         private final int mResponseSpeed;
         private InstrumentsCallback mCallback;
 
-        TestPay(String methodName, int instrumentPresence, int responseSpeed) {
-            mMethodName = methodName;
+        TestPay(List<String> methodNames, int instrumentPresence, int responseSpeed) {
+            mMethodNames = methodNames;
             mInstrumentPresence = instrumentPresence;
             mResponseSpeed = responseSpeed;
         }
@@ -899,7 +907,10 @@
         void respond() {
             final List<PaymentInstrument> instruments = new ArrayList<>();
             if (mInstrumentPresence == HAVE_INSTRUMENTS) {
-                instruments.add(new TestPayInstrument(mMethodName));
+                for (String methodName : mMethodNames) {
+                    instruments.add(
+                            new TestPayInstrument(getAppIdentifier(), methodName, methodName));
+                }
             }
             Runnable instrumentsReady = new Runnable() {
                 @Override
@@ -918,19 +929,21 @@
         @Override
         public Set<String> getAppMethodNames() {
             Set<String> methodNames = new HashSet<>();
-            methodNames.add(mMethodName);
+            methodNames.addAll(mMethodNames);
             return methodNames;
         }
 
         @Override
         public boolean supportsMethodsAndData(Map<String, PaymentMethodData> methodsAndData) {
             assert methodsAndData != null;
-            return methodsAndData.containsKey(mMethodName);
+            Set<String> methodNames = new HashSet<>(methodsAndData.keySet());
+            methodNames.retainAll(getAppMethodNames());
+            return !methodNames.isEmpty();
         }
 
         @Override
         public String getAppIdentifier() {
-            return mMethodName;
+            return TestPay.this.toString();
         }
     }
 
@@ -938,8 +951,8 @@
     private static class TestPayInstrument extends PaymentInstrument {
         private final String mMethodName;
 
-        TestPayInstrument(String methodName) {
-            super(methodName, "Test Pay", null, null);
+        TestPayInstrument(String appId, String methodName, String label) {
+            super(appId + methodName, label, null, null);
             mMethodName = methodName;
         }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/UrlManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/UrlManagerTest.java
index 90d1920..c7fffc7 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/UrlManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/UrlManagerTest.java
@@ -10,6 +10,7 @@
 
 import org.chromium.base.ContextUtils;
 import org.chromium.base.test.util.DisabledTest;
+import org.chromium.base.test.util.FlakyTest;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
@@ -271,6 +272,7 @@
         assertTrue(urlManager.containsInAnyCache(URL2));
     }
 
+    @FlakyTest(message = "https://crbug.com/685471")
     @SmallTest
     @RetryOnFailure
     public void testSerializationWorksWithoutGarbageCollection() throws Exception {
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index ea88d61..41c1e21 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5885,12 +5885,6 @@
         <message name="IDS_FLAGS_ASH_ENABLE_DOCKED_WINDOWS_DESCRIPTION" desc="Description for the flag which can be used to enable docking windows to right or left.">
           Enable docking windows to the left and right of the screen.
         </message>
-        <message name="IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_NAME" desc="Title for the flag which can be used to test the TouchView maximizing mode.">
-          Enable TouchView maximizing UI for testing
-        </message>
-        <message name="IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_DESCRIPTION" desc="Description for the flag to enable the TouchView testing mode.">
-          Enable Ctrl+Alt+Shift+8 to toggle the TouchView maximizing mode.
-        </message>
         <message name="IDS_FLAGS_ASH_ENABLE_MIRRORED_SCREEN_NAME" desc="Title for the flag to enable the mirrored screen mode.">
           Enable mirrored screen mode.
         </message>
diff --git a/chrome/app/mash/BUILD.gn b/chrome/app/mash/BUILD.gn
index e78d037..981d813 100644
--- a/chrome/app/mash/BUILD.gn
+++ b/chrome/app/mash/BUILD.gn
@@ -11,7 +11,7 @@
     "mash_runner.h",
   ]
   deps = [
-    ":catalog_cpp_source",
+    ":chrome_mash_catalog",
     "//base:i18n",
     "//components/tracing:startup_tracing",
     "//content/public/common",
@@ -77,7 +77,7 @@
   catalog_deps = [ "//chrome/app:catalog" ]
 }
 
-catalog_cpp_source("catalog_cpp_source") {
+catalog_cpp_source("chrome_mash_catalog") {
   catalog = ":catalog"
-  output_symbol_name = "kChromeMashCatalogContents"
+  generated_function_name = "CreateChromeMashCatalog"
 }
diff --git a/chrome/app/mash/mash_runner.cc b/chrome/app/mash/mash_runner.cc
index 42c50057..f4720fb0 100644
--- a/chrome/app/mash/mash_runner.cc
+++ b/chrome/app/mash/mash_runner.cc
@@ -15,7 +15,6 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/i18n/icu_util.h"
-#include "base/json/json_reader.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
@@ -28,6 +27,7 @@
 #include "base/threading/sequenced_worker_pool.h"
 #include "base/threading/thread.h"
 #include "base/trace_event/trace_event.h"
+#include "chrome/app/mash/chrome_mash_catalog.h"
 #include "components/tracing/common/trace_to_console.h"
 #include "components/tracing/common/tracing_switches.h"
 #include "content/public/common/content_switches.h"
@@ -61,9 +61,6 @@
 
 using service_manager::mojom::ServiceFactory;
 
-// Defined externally by the ":catalog_cpp_source" target.
-extern const char kChromeMashCatalogContents[];
-
 namespace {
 
 // kProcessType used to identify child processes.
@@ -177,16 +174,12 @@
       ipc_thread.task_runner(),
       mojo::edk::ScopedIPCSupport::ShutdownPolicy::FAST);
 
-  std::unique_ptr<base::Value> manifest_value =
-      base::JSONReader::Read(kChromeMashCatalogContents);
-  DCHECK(manifest_value);
-
   // TODO(sky): refactor BackgroundServiceManager so can supply own context, we
   // shouldn't we using context as it has a lot of stuff we don't really want
   // in chrome.
   ServiceProcessLauncherDelegateImpl service_process_launcher_delegate;
   service_manager::BackgroundServiceManager background_service_manager(
-      &service_process_launcher_delegate, std::move(manifest_value));
+      &service_process_launcher_delegate, CreateChromeMashCatalog());
   service_manager::mojom::ServicePtr service;
   context_.reset(new service_manager::ServiceContext(
       base::MakeUnique<mash::MashPackagedService>(),
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index e25e527..feb95051 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1041,12 +1041,6 @@
         SINGLE_VALUE_TYPE(ash::switches::kAshEnableDockedWindows),
     },
     {
-        "ash-enable-touch-view-testing",
-        IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_NAME,
-        IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_DESCRIPTION, kOsCrOS,
-        SINGLE_VALUE_TYPE(ash::switches::kAshEnableTouchViewTesting),
-    },
-    {
         "ash-enable-mirrored-screen", IDS_FLAGS_ASH_ENABLE_MIRRORED_SCREEN_NAME,
         IDS_FLAGS_ASH_ENABLE_MIRRORED_SCREEN_DESCRIPTION, kOsCrOS,
         SINGLE_VALUE_TYPE(ash::switches::kAshEnableMirroredScreen),
@@ -1306,9 +1300,6 @@
      SINGLE_VALUE_TYPE(app_list::switches::kResetAppListInstallState)},
 #endif  // BUILDFLAG(ENABLE_APP_LIST)
 #if defined(OS_ANDROID)
-    {"enable-downloads-ui", IDS_FLAGS_ENABLE_DOWNLOADS_UI_NAME,
-     IDS_FLAGS_ENABLE_DOWNLOADS_UI_DESCRIPTION, kOsAndroid,
-     FEATURE_VALUE_TYPE(chrome::android::kDownloadsUiFeature)},
     {"enable-special-locale", IDS_FLAGS_ENABLE_SPECIAL_LOCALE_NAME,
      IDS_FLAGS_ENABLE_SPECIAL_LOCALE_DESCRIPTION, kOsAndroid,
      FEATURE_VALUE_TYPE(chrome::android::kSpecialLocaleFeature)},
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index fb40a0d..d2d8bc2 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -45,7 +45,6 @@
     &kCCTPostMessageAPI,
     &kChromeHomeFeature,
     &kContextualSearchSingleActions,
-    &kDownloadsUiFeature,
     &kImportantSitesInCBD,
     &kImprovedA2HS,
     &kNativeAndroidHistoryManager,
@@ -97,9 +96,6 @@
 const base::Feature kContextualSearchSingleActions{
     "ContextualSearchSingleActions", base::FEATURE_DISABLED_BY_DEFAULT};
 
-const base::Feature kDownloadsUiFeature{"DownloadsUi",
-                                         base::FEATURE_DISABLED_BY_DEFAULT};
-
 const base::Feature kImportantSitesInCBD{"ImportantSitesInCBD",
                                          base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h
index b1f084c1..e7e6ea2c 100644
--- a/chrome/browser/android/chrome_feature_list.h
+++ b/chrome/browser/android/chrome_feature_list.h
@@ -20,7 +20,6 @@
 extern const base::Feature kCCTPostMessageAPI;
 extern const base::Feature kChromeHomeFeature;
 extern const base::Feature kContextualSearchSingleActions;
-extern const base::Feature kDownloadsUiFeature;
 extern const base::Feature kImportantSitesInCBD;
 extern const base::Feature kImprovedA2HS;
 extern const base::Feature kNativeAndroidHistoryManager;
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 05383ffe..7bed2f2 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -633,6 +633,12 @@
       <if expr="is_win">
         <include name="IDR_NACL_BROKER_MANIFEST" file="../../components/nacl/broker/nacl_broker_manifest.json" type="BINDATA" />
       </if>
+      <if expr="is_win">
+        <include name="IDR_WELCOME_WIN10_DEFAULT_LARGE_WEBP" file="resources\welcome\win10\default-large.webp" type="BINDATA" />
+        <include name="IDR_WELCOME_WIN10_DEFAULT_SMALL_WEBP" file="resources\welcome\win10\default-small.webp" type="BINDATA" />
+        <include name="IDR_WELCOME_WIN10_PIN_LARGE_WEBP" file="resources\welcome\win10\pin-large.webp" type="BINDATA" />
+        <include name="IDR_WELCOME_WIN10_PIN_SMALL_WEBP" file="resources\welcome\win10\pin-small.webp" type="BINDATA" />
+      </if>
     </includes>
   </release>
 </grit>
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index a6196c2b..781d198 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1193,6 +1193,8 @@
     "printing/printer_pref_manager.h",
     "printing/printer_pref_manager_factory.cc",
     "printing/printer_pref_manager_factory.h",
+    "printing/specifics_translation.cc",
+    "printing/specifics_translation.h",
     "profiles/avatar_menu_actions_chromeos.cc",
     "profiles/avatar_menu_actions_chromeos.h",
     "profiles/avatar_menu_chromeos.cc",
@@ -1620,6 +1622,7 @@
     "preferences_unittest.cc",
     "printer_detector/printer_detector_unittest.cc",
     "printing/printer_pref_manager_unittest.cc",
+    "printing/specifics_translation_unittest.cc",
     "profiles/profile_list_chromeos_unittest.cc",
     "proxy_config_service_impl_unittest.cc",
     "resource_reporter/resource_reporter_unittest.cc",
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
index 44b3116..054f8fe 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
@@ -40,6 +40,7 @@
 #include "chromeos/cryptohome/async_method_caller.h"
 #include "chromeos/cryptohome/cryptohome_parameters.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/session_manager_client.h"
 #include "chromeos/settings/cros_settings_names.h"
 #include "components/ownership/owner_key_util.h"
 #include "components/prefs/pref_registry_simple.h"
@@ -51,6 +52,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "extensions/common/extension_urls.h"
 #include "extensions/common/manifest_handlers/kiosk_mode_info.h"
+#include "third_party/cros_system_api/switches/chrome_switches.h"
 
 namespace chromeos {
 
@@ -147,6 +149,14 @@
                                           minor_version, bugfix_version));
 }
 
+// Converts a flag constant to actual command line switch value.
+std::string GetSwitchString(const std::string& flag_name) {
+  base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM);
+  cmd_line.AppendSwitch(flag_name);
+  DCHECK_EQ(2U, cmd_line.argv().size());
+  return cmd_line.argv()[1];
+}
+
 }  // namespace
 
 // static
@@ -241,10 +251,70 @@
                                    const std::string& app_id) {
   LOG_IF(FATAL, app_session_) << "Kiosk session is already initialized.";
 
+  base::CommandLine session_flags(base::CommandLine::NO_PROGRAM);
+  if (GetSwitchesForSessionRestore(app_id, &session_flags)) {
+    base::CommandLine::StringVector flags;
+    // argv[0] is the program name |base::CommandLine::NO_PROGRAM|.
+    flags.assign(session_flags.argv().begin() + 1, session_flags.argv().end());
+
+    // Update user flags, but do not restart Chrome - the purpose of the flags
+    // set here is to be able to properly restore session if the session is
+    // restarted - e.g. due to crash. For example, this will ensure restarted
+    // app session restores auto-launched state.
+    DBusThreadManager::Get()->GetSessionManagerClient()->SetFlagsForUser(
+        cryptohome::Identification(
+            user_manager::UserManager::Get()->GetActiveUser()->GetAccountId()),
+        flags);
+  }
+
   app_session_.reset(new AppSession);
   app_session_->Init(profile, app_id);
 }
 
+bool KioskAppManager::GetSwitchesForSessionRestore(
+    const std::string& app_id,
+    base::CommandLine* switches) {
+  bool auto_launched = app_id == currently_auto_launched_with_zero_delay_app_;
+  const base::CommandLine* current_command_line =
+      base::CommandLine::ForCurrentProcess();
+  bool has_auto_launched_flag =
+      current_command_line->HasSwitch(switches::kAppAutoLaunched);
+  if (auto_launched == has_auto_launched_flag)
+    return false;
+
+  // Collect current policy defined switches, so they can be passed on to the
+  // session manager as well - otherwise they would get lost on restart.
+  // This ignores 'flag-switches-begin' - 'flag-switches-end' flags, but those
+  // should not be present for kiosk sessions.
+  bool in_policy_switches_block = false;
+  const std::string policy_switches_begin =
+      GetSwitchString(switches::kPolicySwitchesBegin);
+  const std::string policy_switches_end =
+      GetSwitchString(switches::kPolicySwitchesEnd);
+
+  for (const auto& it : current_command_line->argv()) {
+    if (it == policy_switches_begin) {
+      DCHECK(!in_policy_switches_block);
+      in_policy_switches_block = true;
+    }
+
+    if (in_policy_switches_block)
+      switches->AppendSwitch(it);
+
+    if (it == policy_switches_end) {
+      DCHECK(in_policy_switches_block);
+      in_policy_switches_block = false;
+    }
+  }
+
+  DCHECK(!in_policy_switches_block);
+
+  if (auto_launched)
+    switches->AppendSwitch(switches::kAppAutoLaunched);
+
+  return true;
+}
+
 void KioskAppManager::AddAppForTest(
     const std::string& app_id,
     const AccountId& account_id,
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
index 7aac2e7..f057d11 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
@@ -26,6 +26,10 @@
 class PrefRegistrySimple;
 class Profile;
 
+namespace base {
+class CommandLine;
+}
+
 namespace extensions {
 class Extension;
 class ExternalLoader;
@@ -317,6 +321,15 @@
   // Returns the auto launch delay.
   base::TimeDelta GetAutoLaunchDelay() const;
 
+  // Gets list of user switches that should be passed to Chrome in case current
+  // session has to be restored, e.g. in case of a crash. The switches will be
+  // returned as |switches| command line arguments.
+  // Returns whether the set of switches would have to be changed in respect to
+  // the current set of switches - if that is not the case |switches| might not
+  // get populated.
+  bool GetSwitchesForSessionRestore(const std::string& app_id,
+                                    base::CommandLine* switches);
+
   // True if machine ownership is already established.
   bool ownership_established_;
   std::vector<std::unique_ptr<KioskAppData>> apps_;
diff --git a/chrome/browser/chromeos/app_mode/kiosk_crash_restore_browsertest.cc b/chrome/browser/chromeos/app_mode/kiosk_crash_restore_browsertest.cc
deleted file mode 100644
index 703a763..0000000
--- a/chrome/browser/chromeos/app_mode/kiosk_crash_restore_browsertest.cc
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <string>
-
-#include "apps/test/app_window_waiter.h"
-#include "base/base64.h"
-#include "base/command_line.h"
-#include "base/files/file_util.h"
-#include "base/path_service.h"
-#include "base/run_loop.h"
-#include "chrome/browser/chromeos/app_mode/fake_cws.h"
-#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
-#include "chrome/browser/chromeos/net/network_portal_detector_test_impl.h"
-#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
-#include "chrome/browser/chromeos/policy/device_local_account.h"
-#include "chrome/browser/chromeos/policy/device_policy_builder.h"
-#include "chrome/browser/extensions/browsertest_util.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "chromeos/chromeos_switches.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_session_manager_client.h"
-#include "chromeos/dbus/fake_shill_manager_client.h"
-#include "components/ownership/mock_owner_key_util.h"
-#include "extensions/browser/app_window/app_window.h"
-#include "extensions/browser/app_window/app_window_registry.h"
-#include "extensions/browser/app_window/native_app_window.h"
-#include "extensions/common/value_builder.h"
-#include "extensions/test/extension_test_message_listener.h"
-#include "net/dns/mock_host_resolver.h"
-
-namespace em = enterprise_management;
-
-namespace chromeos {
-
-namespace {
-
-const char kTestKioskApp[] = "ggbflgnkafappblpkiflbgpmkfdpnhhe";
-
-}  // namespace
-
-class KioskCrashRestoreTest : public InProcessBrowserTest {
- public:
-  KioskCrashRestoreTest()
-      : owner_key_util_(new ownership::MockOwnerKeyUtil()),
-        fake_cws_(new FakeCWS) {}
-
-  // InProcessBrowserTest
-  void SetUp() override {
-    ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
-    InProcessBrowserTest::SetUp();
-  }
-
-  bool SetUpUserDataDirectory() override {
-    SetUpExistingKioskApp();
-    return true;
-  }
-
-  void SetUpInProcessBrowserTestFixture() override {
-    host_resolver()->AddRule("*", "127.0.0.1");
-    SimulateNetworkOnline();
-
-    OverrideDevicePolicy();
-  }
-
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    const AccountId account_id = AccountId::FromUserEmail(GetTestAppUserId());
-    const cryptohome::Identification cryptohome_id(account_id);
-
-    command_line->AppendSwitchASCII(switches::kLoginUser, cryptohome_id.id());
-    command_line->AppendSwitchASCII(
-        switches::kLoginProfile,
-        CryptohomeClient::GetStubSanitizedUsername(cryptohome_id));
-
-    fake_cws_->Init(embedded_test_server());
-    fake_cws_->SetUpdateCrx(test_app_id_, test_app_id_ + ".crx", "1.0.0");
-  }
-
-  void SetUpOnMainThread() override {
-    extensions::browsertest_util::CreateAndInitializeLocalCache();
-
-    embedded_test_server()->StartAcceptingConnections();
-  }
-
-  const std::string GetTestAppUserId() const {
-    return policy::GenerateDeviceLocalAccountUserId(
-        test_app_id_, policy::DeviceLocalAccount::TYPE_KIOSK_APP);
-  }
-
-  const std::string& test_app_id() const { return test_app_id_; }
-
- private:
-  void SetUpExistingKioskApp() {
-    // Create policy data that contains the test app as an existing kiosk app.
-    em::DeviceLocalAccountsProto* const device_local_accounts =
-        device_policy_.payload().mutable_device_local_accounts();
-
-    em::DeviceLocalAccountInfoProto* const account =
-        device_local_accounts->add_account();
-    account->set_account_id(test_app_id_);
-    account->set_type(
-        em::DeviceLocalAccountInfoProto_AccountType_ACCOUNT_TYPE_KIOSK_APP);
-    account->mutable_kiosk_app()->set_app_id(test_app_id_);
-    device_policy_.Build();
-
-    // Prepare the policy data to store in device policy cache.
-    em::PolicyData policy_data;
-    CHECK(device_policy_.payload().SerializeToString(
-        policy_data.mutable_policy_value()));
-    const std::string policy_data_string = policy_data.SerializeAsString();
-    std::string encoded;
-    base::Base64Encode(policy_data_string, &encoded);
-
-    // Store policy data and existing device local accounts in local state.
-    const std::string local_state_json =
-        extensions::DictionaryBuilder()
-            .Set(prefs::kDeviceSettingsCache, encoded)
-            .Set("PublicAccounts",
-                 extensions::ListBuilder().Append(GetTestAppUserId()).Build())
-            .ToJSON();
-
-    base::FilePath local_state_file;
-    CHECK(PathService::Get(chrome::DIR_USER_DATA, &local_state_file));
-    local_state_file = local_state_file.Append(chrome::kLocalStateFilename);
-    base::WriteFile(local_state_file, local_state_json.data(),
-                    local_state_json.size());
-  }
-
-  void SimulateNetworkOnline() {
-    NetworkPortalDetectorTestImpl* const network_portal_detector =
-        new NetworkPortalDetectorTestImpl();
-    // Takes ownership of |network_portal_detector|.
-    network_portal_detector::InitializeForTesting(network_portal_detector);
-    network_portal_detector->SetDefaultNetworkForTesting(
-        FakeShillManagerClient::kFakeEthernetNetworkGuid);
-
-    NetworkPortalDetector::CaptivePortalState online_state;
-    online_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE;
-    online_state.response_code = 204;
-    network_portal_detector->SetDetectionResultsForTesting(
-        FakeShillManagerClient::kFakeEthernetNetworkGuid, online_state);
-  }
-
-  void OverrideDevicePolicy() {
-    OwnerSettingsServiceChromeOSFactory::GetInstance()
-        ->SetOwnerKeyUtilForTesting(owner_key_util_);
-    owner_key_util_->SetPublicKeyFromPrivateKey(
-        *device_policy_.GetSigningKey());
-
-    session_manager_client_ = new FakeSessionManagerClient;
-    session_manager_client_->set_device_policy(device_policy_.GetBlob());
-
-    DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient(
-        std::unique_ptr<SessionManagerClient>(session_manager_client_));
-  }
-
-  std::string test_app_id_ = kTestKioskApp;
-
-  policy::DevicePolicyBuilder device_policy_;
-  scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util_;
-  FakeSessionManagerClient* session_manager_client_;
-  std::unique_ptr<FakeCWS> fake_cws_;
-
-  DISALLOW_COPY_AND_ASSIGN(KioskCrashRestoreTest);
-};
-
-IN_PROC_BROWSER_TEST_F(KioskCrashRestoreTest, Basic) {
-  ExtensionTestMessageListener launch_data_check_listener(
-      "launchData.isKioskSession = true", false);
-
-  Profile* const app_profile = ProfileManager::GetPrimaryUserProfile();
-  ASSERT_TRUE(app_profile);
-  extensions::AppWindowRegistry* const app_window_registry =
-      extensions::AppWindowRegistry::Get(app_profile);
-  extensions::AppWindow* const window =
-      apps::AppWindowWaiter(app_window_registry, test_app_id()).Wait();
-  ASSERT_TRUE(window);
-
-  window->GetBaseWindow()->Close();
-
-  // Wait until the app terminates if it is still running.
-  if (!app_window_registry->GetAppWindowsForApp(test_app_id()).empty())
-    base::RunLoop().Run();
-
-  EXPECT_TRUE(launch_data_check_listener.was_satisfied());
-}
-
-}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/auto_launched_kiosk_browsertest.cc b/chrome/browser/chromeos/login/auto_launched_kiosk_browsertest.cc
new file mode 100644
index 0000000..703174e8
--- /dev/null
+++ b/chrome/browser/chromeos/login/auto_launched_kiosk_browsertest.cc
@@ -0,0 +1,482 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "apps/test/app_window_waiter.h"
+#include "base/base64.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/json/json_file_value_serializer.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/run_loop.h"
+#include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/chromeos/app_mode/fake_cws.h"
+#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
+#include "chrome/browser/chromeos/login/app_launch_controller.h"
+#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
+#include "chrome/browser/chromeos/policy/device_local_account.h"
+#include "chrome/browser/chromeos/policy/device_policy_builder.h"
+#include "chrome/browser/chromeos/settings/stub_install_attributes.h"
+#include "chrome/browser/extensions/browsertest_util.h"
+#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/pref_names.h"
+#include "chromeos/dbus/cryptohome_client.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/fake_session_manager_client.h"
+#include "chromeos/dbus/shill_manager_client.h"
+#include "components/ownership/mock_owner_key_util.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "content/public/browser/notification_service.h"
+#include "extensions/browser/app_window/app_window.h"
+#include "extensions/browser/app_window/app_window_registry.h"
+#include "extensions/browser/app_window/native_app_window.h"
+#include "extensions/common/value_builder.h"
+#include "extensions/test/extension_test_message_listener.h"
+#include "net/dns/mock_host_resolver.h"
+#include "third_party/cros_system_api/switches/chrome_switches.h"
+
+namespace em = enterprise_management;
+
+namespace chromeos {
+
+namespace {
+
+// This is a simple test app that creates an app window and immediately closes
+// it again. Webstore data json is in
+//   chrome/test/data/chromeos/app_mode/webstore/inlineinstall/
+//       detail/ggbflgnkafappblpkiflbgpmkfdpnhhe
+const char kTestKioskApp[] = "ggbflgnkafappblpkiflbgpmkfdpnhhe";
+
+const char kTestAccountId[] = "enterprise-kiosk-app@localhost";
+
+const char kSessionManagerStateCache[] = "test_session_manager_state.json";
+
+// Keys for values in dictionary used to preserve session manager state.
+const char kLoginArgsKey[] = "login_args";
+const char kExtraArgsKey[] = "extra_args";
+const char kArgNameKey[] = "name";
+const char kArgValueKey[] = "value";
+
+// Default set policy switches.
+const struct {
+  const char* name;
+  const char* value;
+} kDefaultPolicySwitches[] = {{"test_switch_1", ""},
+                              {"test_switch_2", "test_switch_2_value"}};
+
+// Fake session manager implementation that persists its state in local file.
+// It can be used to preserve session state in PRE_ browser tests.
+// Primarily used for testing user/login switches.
+class PersistentSessionManagerClient : public FakeSessionManagerClient {
+ public:
+  PersistentSessionManagerClient() {}
+
+  ~PersistentSessionManagerClient() override {
+    PersistFlagsToFile(backing_file_);
+  }
+
+  // Initializes session state (primarily session flags)- if |backing_file|
+  // exists, the session state is restored from the file value. Otherwise it's
+  // set to the default session state.
+  void Initialize(const base::FilePath& backing_file) {
+    backing_file_ = backing_file;
+
+    if (ExtractFlagsFromFile(backing_file_))
+      return;
+
+    // Failed to extract ached flags - set the default values.
+    login_args_ = {{"login-manager", ""}};
+
+    extra_args_ = {{switches::kPolicySwitchesBegin, ""}};
+    for (size_t i = 0; i < arraysize(kDefaultPolicySwitches); ++i) {
+      extra_args_.push_back(
+          {kDefaultPolicySwitches[i].name, kDefaultPolicySwitches[i].value});
+    }
+    extra_args_.push_back({switches::kPolicySwitchesEnd, ""});
+  }
+
+  void AppendSwitchesToCommandLine(base::CommandLine* command_line) {
+    for (const auto& flag : login_args_)
+      command_line->AppendSwitchASCII(flag.name, flag.value);
+    for (const auto& flag : extra_args_)
+      command_line->AppendSwitchASCII(flag.name, flag.value);
+  }
+
+  void StartSession(const cryptohome::Identification& cryptohome_id) override {
+    FakeSessionManagerClient::StartSession(cryptohome_id);
+
+    std::string user_id_hash =
+        CryptohomeClient::GetStubSanitizedUsername(cryptohome_id);
+    login_args_ = {{"login-user", cryptohome_id.id()},
+                   {"login-profile", user_id_hash}};
+  }
+
+  void StopSession() override {
+    FakeSessionManagerClient::StopSession();
+
+    login_args_ = {{"login-manager", ""}};
+  }
+
+  bool SupportsRestartToApplyUserFlags() const override { return true; }
+
+  void SetFlagsForUser(const cryptohome::Identification& identification,
+                       const std::vector<std::string>& flags) override {
+    extra_args_.clear();
+    FakeSessionManagerClient::SetFlagsForUser(identification, flags);
+
+    std::vector<std::string> argv = {"" /* Empty program */};
+    argv.insert(argv.end(), flags.begin(), flags.end());
+
+    // Parse flag name-value pairs using command line initialization.
+    base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM);
+    cmd_line.InitFromArgv(argv);
+
+    for (const auto& flag : cmd_line.GetSwitches())
+      extra_args_.push_back({flag.first, flag.second});
+  }
+
+ private:
+  // Keeps information about a switch - its name and value.
+  struct Switch {
+    std::string name;
+    std::string value;
+  };
+
+  bool ExtractFlagsFromFile(const base::FilePath& backing_file) {
+    JSONFileValueDeserializer deserializer(backing_file);
+
+    int error_code = 0;
+    std::unique_ptr<base::Value> value =
+        deserializer.Deserialize(&error_code, nullptr);
+    if (error_code != JSONFileValueDeserializer::JSON_NO_ERROR)
+      return false;
+
+    std::unique_ptr<base::DictionaryValue> value_dict =
+        base::DictionaryValue::From(std::move(value));
+    CHECK(value_dict);
+
+    CHECK(InitArgListFromCachedValue(*value_dict, kLoginArgsKey, &login_args_));
+    CHECK(InitArgListFromCachedValue(*value_dict, kExtraArgsKey, &extra_args_));
+    return true;
+  }
+
+  bool PersistFlagsToFile(const base::FilePath& backing_file) {
+    base::DictionaryValue cached_state;
+    cached_state.Set(kLoginArgsKey, GetArgListValue(login_args_));
+    cached_state.Set(kExtraArgsKey, GetArgListValue(extra_args_));
+
+    JSONFileValueSerializer serializer(backing_file);
+    return serializer.Serialize(cached_state);
+  }
+
+  std::unique_ptr<base::ListValue> GetArgListValue(
+      const std::vector<Switch>& args) {
+    std::unique_ptr<base::ListValue> result(new base::ListValue());
+    for (const auto& arg : args) {
+      result->Append(extensions::DictionaryBuilder()
+                         .Set(kArgNameKey, arg.name)
+                         .Set(kArgValueKey, arg.value)
+                         .Build());
+    }
+    return result;
+  }
+
+  bool InitArgListFromCachedValue(const base::DictionaryValue& cache_value,
+                                  const std::string& list_key,
+                                  std::vector<Switch>* arg_list_out) {
+    arg_list_out->clear();
+    const base::ListValue* arg_list_value;
+    if (!cache_value.GetList(list_key, &arg_list_value))
+      return false;
+    for (size_t i = 0; i < arg_list_value->GetSize(); ++i) {
+      const base::DictionaryValue* arg_value;
+      if (!arg_list_value->GetDictionary(i, &arg_value))
+        return false;
+      Switch arg;
+      if (!arg_value->GetStringASCII(kArgNameKey, &arg.name) ||
+          !arg_value->GetStringASCII(kArgValueKey, &arg.value)) {
+        return false;
+      }
+      arg_list_out->push_back(arg);
+    }
+    return true;
+  }
+
+  std::vector<Switch> login_args_;
+  std::vector<Switch> extra_args_;
+
+  base::FilePath backing_file_;
+
+  DISALLOW_COPY_AND_ASSIGN(PersistentSessionManagerClient);
+};
+
+// Used to listen for app termination notification.
+class TerminationObserver : public content::NotificationObserver {
+ public:
+  TerminationObserver() {
+    registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
+                   content::NotificationService::AllSources());
+  }
+  ~TerminationObserver() override = default;
+
+  // Whether app has been terminated - i.e. whether app termination notification
+  // has been observed.
+  bool terminated() const { return notification_seen_; }
+
+ private:
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override {
+    ASSERT_EQ(chrome::NOTIFICATION_APP_TERMINATING, type);
+    notification_seen_ = true;
+  }
+
+  bool notification_seen_ = false;
+  content::NotificationRegistrar registrar_;
+
+  DISALLOW_COPY_AND_ASSIGN(TerminationObserver);
+};
+
+}  // namespace
+
+class AutoLaunchedKioskTest : public ExtensionApiTest {
+ public:
+  AutoLaunchedKioskTest()
+      : install_attributes_(
+            chromeos::ScopedStubInstallAttributes::CreateEnterprise(
+                "domain.com",
+                "device_id")),
+        owner_key_util_(new ownership::MockOwnerKeyUtil()),
+        fake_session_manager_(new PersistentSessionManagerClient()),
+        fake_cws_(new FakeCWS) {
+    set_chromeos_user_ = false;
+  }
+
+  ~AutoLaunchedKioskTest() override = default;
+
+  void SetUp() override {
+    ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
+    AppLaunchController::SkipSplashWaitForTesting();
+
+    ExtensionApiTest::SetUp();
+  }
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    fake_cws_->Init(embedded_test_server());
+    fake_cws_->SetUpdateCrx(kTestKioskApp, std::string(kTestKioskApp) + ".crx",
+                            "1.0.0");
+    ExtensionApiTest::SetUpCommandLine(command_line);
+  }
+
+  bool SetUpUserDataDirectory() override {
+    InitDevicePolicy();
+
+    base::FilePath user_data_path;
+    if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_path)) {
+      ADD_FAILURE() << "Unable to get used data dir";
+      return false;
+    }
+
+    if (!CacheDevicePolicyToLocalState(user_data_path))
+      return false;
+
+    // Restore session_manager state and ensure session manager flags are
+    // applied.
+    fake_session_manager_->Initialize(
+        user_data_path.Append(kSessionManagerStateCache));
+    fake_session_manager_->AppendSwitchesToCommandLine(
+        base::CommandLine::ForCurrentProcess());
+
+    return true;
+  }
+
+  void SetUpInProcessBrowserTestFixture() override {
+    host_resolver()->AddRule("*", "127.0.0.1");
+
+    OwnerSettingsServiceChromeOSFactory::GetInstance()
+        ->SetOwnerKeyUtilForTesting(owner_key_util_);
+    owner_key_util_->SetPublicKeyFromPrivateKey(
+        *device_policy_.GetSigningKey());
+
+    fake_session_manager_->set_device_policy(device_policy_.GetBlob());
+    DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient(
+        std::move(fake_session_manager_));
+
+    ExtensionApiTest::SetUpInProcessBrowserTestFixture();
+  }
+
+  void SetUpOnMainThread() override {
+    extensions::browsertest_util::CreateAndInitializeLocalCache();
+
+    embedded_test_server()->StartAcceptingConnections();
+
+    ExtensionApiTest::SetUpOnMainThread();
+  }
+
+  void RunTestOnMainThreadLoop() override {
+    termination_observer_.reset(new TerminationObserver());
+
+    ExtensionApiTest::RunTestOnMainThreadLoop();
+  }
+
+  void TearDownOnMainThread() override {
+    termination_observer_.reset();
+
+    ExtensionApiTest::TearDownOnMainThread();
+  }
+
+  void InitDevicePolicy() {
+    // Create device policy, and cache it to local state.
+    em::DeviceLocalAccountsProto* const device_local_accounts =
+        device_policy_.payload().mutable_device_local_accounts();
+
+    em::DeviceLocalAccountInfoProto* const account =
+        device_local_accounts->add_account();
+    account->set_account_id(kTestAccountId);
+    account->set_type(em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_KIOSK_APP);
+    account->mutable_kiosk_app()->set_app_id(kTestKioskApp);
+
+    device_local_accounts->set_auto_login_id(kTestAccountId);
+
+    device_policy_.Build();
+  }
+
+  bool CacheDevicePolicyToLocalState(const base::FilePath& user_data_path) {
+    em::PolicyData policy_data;
+    if (!device_policy_.payload().SerializeToString(
+            policy_data.mutable_policy_value())) {
+      ADD_FAILURE() << "Failed to serialize device policy.";
+      return false;
+    }
+    const std::string policy_data_str = policy_data.SerializeAsString();
+    std::string policy_data_encoded;
+    base::Base64Encode(policy_data_str, &policy_data_encoded);
+
+    std::unique_ptr<base::DictionaryValue> local_state =
+        extensions::DictionaryBuilder()
+            .Set(prefs::kDeviceSettingsCache, policy_data_encoded)
+            .Set("PublicAccounts",
+                 extensions::ListBuilder().Append(GetTestAppUserId()).Build())
+            .Build();
+
+    JSONFileValueSerializer serializer(
+        user_data_path.Append(chrome::kLocalStateFilename));
+    if (!serializer.Serialize(*local_state)) {
+      ADD_FAILURE() << "Failed to write local state.";
+      return false;
+    }
+    return true;
+  }
+
+  const std::string GetTestAppUserId() const {
+    return policy::GenerateDeviceLocalAccountUserId(
+        kTestAccountId, policy::DeviceLocalAccount::TYPE_KIOSK_APP);
+  }
+
+  bool CloseAppWindow(const std::string& app_id) {
+    Profile* const app_profile = ProfileManager::GetPrimaryUserProfile();
+    if (!app_profile) {
+      ADD_FAILURE() << "No primary (app) profile.";
+      return false;
+    }
+
+    extensions::AppWindowRegistry* const app_window_registry =
+        extensions::AppWindowRegistry::Get(app_profile);
+    extensions::AppWindow* const window =
+        apps::AppWindowWaiter(app_window_registry, app_id).Wait();
+    if (!window) {
+      ADD_FAILURE() << "No app window found for " << app_id << ".";
+      return false;
+    }
+
+    window->GetBaseWindow()->Close();
+
+    // Wait until the app terminates if it is still running.
+    if (!app_window_registry->GetAppWindowsForApp(app_id).empty())
+      base::RunLoop().Run();
+    return true;
+  }
+
+  bool IsKioskAppAutoLaunched(const std::string& app_id) {
+    KioskAppManager::App app;
+    if (!KioskAppManager::Get()->GetApp(app_id, &app)) {
+      ADD_FAILURE() << "App " << app_id << " not found.";
+      return false;
+    }
+    return app.was_auto_launched_with_zero_delay;
+  }
+
+  void ExpectCommandLineHasDefaultPolicySwitches(
+      const base::CommandLine& cmd_line) {
+    for (size_t i = 0u; i < arraysize(kDefaultPolicySwitches); ++i) {
+      EXPECT_TRUE(cmd_line.HasSwitch(kDefaultPolicySwitches[i].name))
+          << "Missing flag " << kDefaultPolicySwitches[i].name;
+      EXPECT_EQ(kDefaultPolicySwitches[i].value,
+                cmd_line.GetSwitchValueASCII(kDefaultPolicySwitches[i].name))
+          << "Invalid value for switch " << kDefaultPolicySwitches[i].name;
+    }
+  }
+
+ protected:
+  std::unique_ptr<TerminationObserver> termination_observer_;
+
+ private:
+  chromeos::ScopedStubInstallAttributes install_attributes_;
+  policy::DevicePolicyBuilder device_policy_;
+  scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util_;
+  std::unique_ptr<PersistentSessionManagerClient> fake_session_manager_;
+  std::unique_ptr<FakeCWS> fake_cws_;
+
+  DISALLOW_COPY_AND_ASSIGN(AutoLaunchedKioskTest);
+};
+
+IN_PROC_BROWSER_TEST_F(AutoLaunchedKioskTest, PRE_CrashRestore) {
+  // Verify that Chrome hasn't already exited, e.g. in order to apply user
+  // session flags.
+  ASSERT_FALSE(termination_observer_->terminated());
+
+  // Set up default network connections, so tests think the device is online.
+  DBusThreadManager::Get()
+      ->GetShillManagerClient()
+      ->GetTestInterface()
+      ->SetupDefaultEnvironment();
+
+  // Check that policy flags have not been lost.
+  ExpectCommandLineHasDefaultPolicySwitches(
+      *base::CommandLine::ForCurrentProcess());
+
+  ExtensionTestMessageListener listener("appWindowLoaded", false);
+  EXPECT_TRUE(listener.WaitUntilSatisfied());
+
+  EXPECT_TRUE(IsKioskAppAutoLaunched(kTestKioskApp));
+
+  ASSERT_TRUE(CloseAppWindow(kTestKioskApp));
+}
+
+IN_PROC_BROWSER_TEST_F(AutoLaunchedKioskTest, CrashRestore) {
+  // Verify that Chrome hasn't already exited, e.g. in order to apply user
+  // session flags.
+  ASSERT_FALSE(termination_observer_->terminated());
+
+  ExpectCommandLineHasDefaultPolicySwitches(
+      *base::CommandLine::ForCurrentProcess());
+
+  ExtensionTestMessageListener listener("appWindowLoaded", false);
+  EXPECT_TRUE(listener.WaitUntilSatisfied());
+
+  EXPECT_TRUE(IsKioskAppAutoLaunched(kTestKioskApp));
+
+  ASSERT_TRUE(CloseAppWindow(kTestKioskApp));
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index fe16fe3..145a9ee 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -581,14 +581,18 @@
   // type has be set before kiosk app controller takes over, as at that point
   // kiosk app profile would already be initialized - feature session type
   // should be set before that.
-  // TODO(tbarzic): Note that this does not work well for auto-launched
-  //     sessions, as information about whether session was auto-launched is not
-  //     persisted over session restart - http://crbug.com/677340.
   if (user->GetType() == user_manager::USER_TYPE_KIOSK_APP) {
     if (base::CommandLine::ForCurrentProcess()->HasSwitch(
             switches::kLoginUser)) {
+      // For kiosk session crash recovery, feature session type has be set
+      // before kiosk app controller takes over, as at that point iosk app
+      // profile would already be initialized - feature session type
+      // should be set before that.
+      bool auto_launched = base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kAppAutoLaunched);
       extensions::SetCurrentFeatureSessionType(
-          extensions::FeatureSessionType::KIOSK);
+          auto_launched ? extensions::FeatureSessionType::AUTOLAUNCHED_KIOSK
+                        : extensions::FeatureSessionType::KIOSK);
     }
     return;
   }
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
index a3f7408..f785b60 100644
--- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
@@ -30,6 +30,7 @@
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
 #include "chrome/browser/chromeos/login/signin/auth_sync_observer.h"
@@ -859,6 +860,13 @@
   // Disable window animation since kiosk app runs in a single full screen
   // window and window animation causes start-up janks.
   command_line->AppendSwitch(wm::switches::kWindowAnimationsDisabled);
+
+  // If restoring auto-launched kiosk session, make sure the app is marked
+  // as auto-launched.
+  if (command_line->HasSwitch(switches::kLoginUser) &&
+      command_line->HasSwitch(switches::kAppAutoLaunched)) {
+    KioskAppManager::Get()->SetAppWasAutoLaunchedWithZeroDelay(kiosk_app_id);
+  }
 }
 
 void ChromeUserManagerImpl::ArcKioskAppLoggedIn(user_manager::User* user) {
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index cbc4ded..b4ad845 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -339,9 +339,6 @@
            GetLocalState()->GetBoolean(prefs::kOobeMdMode))
     SetShowMdOobe(true);
 
-  // Disable md oobe by default in m57.
-  SetShowMdOobe(false);
-
   // TODO(drcrash): Remove this after testing (http://crbug.com/647411).
   if (IsRemoraPairingOobe() || IsSharkRequisition() || IsRemoraRequisition()) {
     SetShowMdOobe(false);
diff --git a/chrome/browser/chromeos/printing/specifics_translation.cc b/chrome/browser/chromeos/printing/specifics_translation.cc
new file mode 100644
index 0000000..1b65c82
--- /dev/null
+++ b/chrome/browser/chromeos/printing/specifics_translation.cc
@@ -0,0 +1,105 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "chrome/browser/chromeos/printing/specifics_translation.h"
+#include "chromeos/printing/printer_configuration.h"
+#include "components/sync/protocol/printer_specifics.pb.h"
+
+namespace chromeos {
+namespace printing {
+
+namespace {
+
+Printer::PpdReference SpecificsToPpd(
+    const sync_pb::PrinterPPDReference& specifics) {
+  Printer::PpdReference ref;
+  if (specifics.has_user_supplied_ppd_url()) {
+    ref.user_supplied_ppd_url = specifics.user_supplied_ppd_url();
+  }
+
+  if (specifics.has_effective_model()) {
+    ref.effective_model = specifics.effective_model();
+
+    if (specifics.has_effective_manufacturer())
+      ref.effective_manufacturer = specifics.effective_manufacturer();
+  }
+
+  return ref;
+}
+
+sync_pb::PrinterPPDReference ReferenceToSpecifics(
+    const Printer::PpdReference& ref) {
+  sync_pb::PrinterPPDReference specifics;
+  if (!ref.user_supplied_ppd_url.empty()) {
+    specifics.set_user_supplied_ppd_url(ref.user_supplied_ppd_url);
+  }
+
+  if (!ref.effective_model.empty()) {
+    specifics.set_effective_model(ref.effective_model);
+
+    if (!ref.effective_manufacturer.empty())
+      specifics.set_effective_manufacturer(ref.effective_manufacturer);
+  }
+
+  return specifics;
+}
+
+}  // namespace
+
+std::unique_ptr<Printer> SpecificsToPrinter(
+    const sync_pb::PrinterSpecifics& specifics) {
+  DCHECK(!specifics.id().empty());
+
+  auto printer = base::MakeUnique<Printer>(specifics.id());
+  printer->set_display_name(specifics.display_name());
+  printer->set_description(specifics.description());
+  printer->set_manufacturer(specifics.manufacturer());
+  printer->set_model(specifics.model());
+  printer->set_uri(specifics.uri());
+  printer->set_uuid(specifics.uuid());
+
+  *printer->mutable_ppd_reference() = SpecificsToPpd(specifics.ppd_reference());
+
+  return printer;
+}
+
+std::unique_ptr<sync_pb::PrinterSpecifics> PrinterToSpecifics(
+    const Printer& printer) {
+  DCHECK(!printer.id().empty());
+
+  auto specifics = base::MakeUnique<sync_pb::PrinterSpecifics>();
+  specifics->set_id(printer.id());
+
+  if (!printer.display_name().empty())
+    specifics->set_display_name(printer.display_name());
+
+  if (!printer.description().empty())
+    specifics->set_description(printer.description());
+
+  if (!printer.manufacturer().empty())
+    specifics->set_manufacturer(printer.manufacturer());
+
+  if (!printer.model().empty())
+    specifics->set_model(printer.model());
+
+  if (!printer.uri().empty())
+    specifics->set_uri(printer.uri());
+
+  if (!printer.uuid().empty())
+    specifics->set_uuid(printer.uuid());
+
+  *specifics->mutable_ppd_reference() =
+      ReferenceToSpecifics(printer.ppd_reference());
+
+  return specifics;
+}
+
+}  // namespace printing
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/printing/specifics_translation.h b/chrome/browser/chromeos/printing/specifics_translation.h
new file mode 100644
index 0000000..fa84491
--- /dev/null
+++ b/chrome/browser/chromeos/printing/specifics_translation.h
@@ -0,0 +1,25 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_PRINTING_SPECIFICS_TRANSLATION_H_
+#define CHROME_BROWSER_CHROMEOS_PRINTING_SPECIFICS_TRANSLATION_H_
+
+#include <memory>
+
+#include "chromeos/printing/printer_configuration.h"
+#include "components/sync/protocol/printer_specifics.pb.h"
+
+namespace chromeos {
+namespace printing {
+
+std::unique_ptr<Printer> SpecificsToPrinter(
+    const sync_pb::PrinterSpecifics& printer);
+
+std::unique_ptr<sync_pb::PrinterSpecifics> PrinterToSpecifics(
+    const Printer& printer);
+
+}  // namespace printing
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_PRINTING_SPECIFICS_TRANSLATION_H_
diff --git a/chrome/browser/chromeos/printing/specifics_translation_unittest.cc b/chrome/browser/chromeos/printing/specifics_translation_unittest.cc
new file mode 100644
index 0000000..e8a2cf9
--- /dev/null
+++ b/chrome/browser/chromeos/printing/specifics_translation_unittest.cc
@@ -0,0 +1,112 @@
+// Copyright 2017 The Chromium 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 <utility>
+
+#include "base/memory/ptr_util.h"
+#include "chrome/browser/chromeos/printing/specifics_translation.h"
+#include "chromeos/printing/printer_configuration.h"
+#include "components/sync/protocol/printer_specifics.pb.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const char id[] = "UNIQUE_ID";
+const char display_name[] = "Best Printer Ever";
+const char description[] = "The green one";
+const char manufacturer[] = "Manufacturer";
+const char model[] = "MODEL";
+const char uri[] = "ipps://notaprinter.chromium.org/ipp/print";
+const char uuid[] = "UUIDUUIDUUID";
+
+const char effective_model[] = "Manufacturer Model T1000";
+
+}  // namespace
+
+namespace chromeos {
+namespace printing {
+
+TEST(SpecificsTranslationTest, SpecificsToPrinter) {
+  sync_pb::PrinterSpecifics specifics;
+  specifics.set_id(id);
+  specifics.set_display_name(display_name);
+  specifics.set_description(description);
+  specifics.set_manufacturer(manufacturer);
+  specifics.set_model(model);
+  specifics.set_uri(uri);
+  specifics.set_uuid(uuid);
+
+  sync_pb::PrinterPPDReference ppd;
+  ppd.set_effective_model(effective_model);
+  *specifics.mutable_ppd_reference() = ppd;
+
+  std::unique_ptr<Printer> result = SpecificsToPrinter(specifics);
+  EXPECT_EQ(id, result->id());
+  EXPECT_EQ(display_name, result->display_name());
+  EXPECT_EQ(description, result->description());
+  EXPECT_EQ(manufacturer, result->manufacturer());
+  EXPECT_EQ(model, result->model());
+  EXPECT_EQ(uri, result->uri());
+  EXPECT_EQ(uuid, result->uuid());
+
+  EXPECT_EQ(effective_model, result->ppd_reference().effective_model);
+}
+
+TEST(SpecificsTranslationTest, PrinterToSpecifics) {
+  Printer printer;
+  printer.set_id(id);
+  printer.set_display_name(display_name);
+  printer.set_description(description);
+  printer.set_manufacturer(manufacturer);
+  printer.set_model(model);
+  printer.set_uri(uri);
+  printer.set_uuid(uuid);
+
+  Printer::PpdReference ppd;
+  ppd.effective_model = effective_model;
+  *printer.mutable_ppd_reference() = ppd;
+
+  std::unique_ptr<sync_pb::PrinterSpecifics> result =
+      PrinterToSpecifics(printer);
+  EXPECT_EQ(id, result->id());
+  EXPECT_EQ(display_name, result->display_name());
+  EXPECT_EQ(description, result->description());
+  EXPECT_EQ(manufacturer, result->manufacturer());
+  EXPECT_EQ(model, result->model());
+  EXPECT_EQ(uri, result->uri());
+  EXPECT_EQ(uuid, result->uuid());
+
+  EXPECT_EQ(effective_model, result->ppd_reference().effective_model());
+}
+
+TEST(SpecificsTranslationTest, SpecificsToPrinterRoundTrip) {
+  Printer printer;
+  printer.set_id(id);
+  printer.set_display_name(display_name);
+  printer.set_description(description);
+  printer.set_manufacturer(manufacturer);
+  printer.set_model(model);
+  printer.set_uri(uri);
+  printer.set_uuid(uuid);
+
+  Printer::PpdReference ppd;
+  ppd.effective_model = effective_model;
+  *printer.mutable_ppd_reference() = ppd;
+
+  std::unique_ptr<sync_pb::PrinterSpecifics> temp = PrinterToSpecifics(printer);
+  std::unique_ptr<Printer> result = SpecificsToPrinter(*temp);
+
+  EXPECT_EQ(id, result->id());
+  EXPECT_EQ(display_name, result->display_name());
+  EXPECT_EQ(description, result->description());
+  EXPECT_EQ(manufacturer, result->manufacturer());
+  EXPECT_EQ(model, result->model());
+  EXPECT_EQ(uri, result->uri());
+  EXPECT_EQ(uuid, result->uuid());
+
+  EXPECT_EQ(effective_model, result->ppd_reference().effective_model);
+}
+
+}  // namespace printing
+}  // namespace chromeos
diff --git a/chrome/browser/media/cast_remoting_sender.cc b/chrome/browser/media/cast_remoting_sender.cc
index bff9116..00de025 100644
--- a/chrome/browser/media/cast_remoting_sender.cc
+++ b/chrome/browser/media/cast_remoting_sender.cc
@@ -92,6 +92,7 @@
       latest_acked_frame_id_(media::cast::FrameId::first() - 1),
       duplicate_ack_counter_(0),
       input_queue_discards_remaining_(0),
+      pipe_watcher_(FROM_HERE),
       flow_restart_pending_(true),
       weak_factory_(this) {
   // Confirm this constructor is running on the IO BrowserThread.
diff --git a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc
index 5c94f10..127a76c 100644
--- a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc
+++ b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc
@@ -126,11 +126,9 @@
                                DownloadHistory* download_history,
                                ContentSuggestionsService* service,
                                PrefService* pref_service) {
-  bool download_manager_ui_enabled =
-      base::FeatureList::IsEnabled(chrome::android::kDownloadsUiFeature);
   auto provider = base::MakeUnique<DownloadSuggestionsProvider>(
       service, offline_page_model, download_manager, download_history,
-      pref_service, download_manager_ui_enabled);
+      pref_service);
   service->RegisterProvider(std::move(provider));
 }
 #endif  // OS_ANDROID
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider.cc b/chrome/browser/ntp_snippets/download_suggestions_provider.cc
index b4f04691..9eb137b 100644
--- a/chrome/browser/ntp_snippets/download_suggestions_provider.cc
+++ b/chrome/browser/ntp_snippets/download_suggestions_provider.cc
@@ -127,8 +127,7 @@
     offline_pages::OfflinePageModel* offline_page_model,
     content::DownloadManager* download_manager,
     DownloadHistory* download_history,
-    PrefService* pref_service,
-    bool download_manager_ui_enabled)
+    PrefService* pref_service)
     : ContentSuggestionsProvider(observer),
       category_status_(CategoryStatus::AVAILABLE_LOADING),
       provided_category_(Category::FromKnownCategory(
@@ -137,7 +136,6 @@
       download_manager_(download_manager),
       download_history_(download_history),
       pref_service_(pref_service),
-      download_manager_ui_enabled_(download_manager_ui_enabled),
       is_asset_downloads_initialization_complete_(false),
       weak_ptr_factory_(this) {
   observer->OnCategoryStatusChanged(this, provided_category_, category_status_);
@@ -192,7 +190,7 @@
       ntp_snippets::ContentSuggestionsCardLayout::MINIMAL_CARD,
       /*has_more_action=*/false,
       /*has_reload_action=*/false,
-      /*has_view_all_action=*/download_manager_ui_enabled_,
+      /*has_view_all_action=*/true,
       /*show_if_empty=*/false,
       l10n_util::GetStringUTF16(IDS_NTP_DOWNLOADS_SUGGESTIONS_SECTION_EMPTY));
 }
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider.h b/chrome/browser/ntp_snippets/download_suggestions_provider.h
index a6f2fb39..59bf356 100644
--- a/chrome/browser/ntp_snippets/download_suggestions_provider.h
+++ b/chrome/browser/ntp_snippets/download_suggestions_provider.h
@@ -46,8 +46,7 @@
       offline_pages::OfflinePageModel* offline_page_model,
       content::DownloadManager* download_manager,
       DownloadHistory* download_history,
-      PrefService* pref_service,
-      bool download_manager_ui_enabled);
+      PrefService* pref_service);
   ~DownloadSuggestionsProvider() override;
 
   // ContentSuggestionsProvider implementation.
@@ -222,10 +221,6 @@
   // the criteria above are cached, otherwise only |kMaxSuggestionsCount|.
   std::vector<const content::DownloadItem*> cached_asset_downloads_;
 
-  // Whether the Download Manager UI is enabled, in which case the More button
-  // for the Downloads section can redirect there.
-  const bool download_manager_ui_enabled_;
-
   bool is_asset_downloads_initialization_complete_;
 
   base::WeakPtrFactory<DownloadSuggestionsProvider> weak_ptr_factory_;
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc b/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc
index 939bbed4..3afefa7 100644
--- a/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc
+++ b/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc
@@ -285,8 +285,7 @@
     provider_ = base::MakeUnique<DownloadSuggestionsProvider>(
         &observer_, show_offline_pages ? &offline_pages_model_ : nullptr,
         show_assets ? &downloads_manager_ : nullptr, &download_history_,
-        pref_service(),
-        /*download_manager_ui_enabled=*/false);
+        pref_service());
     return provider_.get();
   }
 
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index cbff038..5c9cbc87 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -32,6 +32,7 @@
 #include "components/history/core/browser/history_types.h"
 #include "content/public/browser/browser_child_process_host.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
@@ -42,6 +43,7 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
 #include "content/public/common/frame_navigate_params.h"
+#include "net/http/http_response_headers.h"
 #include "services/service_manager/public/cpp/interface_registry.h"
 #include "ui/base/page_transition_types.h"
 #include "ui/gfx/geometry/size.h"
@@ -549,22 +551,21 @@
     NotifyPrerenderDomContentLoaded();
 }
 
-void PrerenderContents::DidStartProvisionalLoadForFrame(
-    content::RenderFrameHost* render_frame_host,
-    const GURL& validated_url,
-    bool is_error_page) {
-  if (!render_frame_host->GetParent()) {
-    if (!CheckURL(validated_url))
-      return;
+void PrerenderContents::DidStartNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle->IsInMainFrame() || navigation_handle->IsSamePage())
+    return;
 
-    // Usually, this event fires if the user clicks or enters a new URL.
-    // Neither of these can happen in the case of an invisible prerender.
-    // So the cause is: Some JavaScript caused a new URL to be loaded.  In that
-    // case, the spinner would start again in the browser, so we must reset
-    // has_stopped_loading_ so that the spinner won't be stopped.
-    has_stopped_loading_ = false;
-    has_finished_loading_ = false;
-  }
+  if (!CheckURL(navigation_handle->GetURL()))
+    return;
+
+  // Usually, this event fires if the user clicks or enters a new URL.
+  // Neither of these can happen in the case of an invisible prerender.
+  // So the cause is: Some JavaScript caused a new URL to be loaded.  In that
+  // case, the spinner would start again in the browser, so we must reset
+  // has_stopped_loading_ so that the spinner won't be stopped.
+  has_stopped_loading_ = false;
+  has_finished_loading_ = false;
 }
 
 void PrerenderContents::DidFinishLoad(
@@ -574,9 +575,29 @@
     has_finished_loading_ = true;
 }
 
-void PrerenderContents::DidNavigateMainFrame(
-    const content::LoadCommittedDetails& details,
-    const content::FrameNavigateParams& params) {
+void PrerenderContents::DidFinishNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle->IsInMainFrame() ||
+      !navigation_handle->HasCommitted() ||
+      navigation_handle->IsErrorPage()) {
+    return;
+  }
+
+  if (navigation_handle->GetResponseHeaders() &&
+      navigation_handle->GetResponseHeaders()->response_code() >= 400) {
+    // Maintain same behavior as old navigation API when the URL is unreachable
+    // and leads to an error page. While there will be a subsequent navigation
+    // that has navigation_handle->IsErrorPage(), it'll be too late to wait for
+    // it as the renderer side will consider this prerender complete. This
+    // object would therefore have been destructed already and so instead look
+    // for the error response code now.
+    // Also maintain same final status code that previous navigation API
+    // returned, which was reached because the URL for the error page was
+    // kUnreachableWebDataURL and that was interpreted as unsupported scheme.
+    Destroy(FINAL_STATUS_UNSUPPORTED_SCHEME);
+    return;
+  }
+
   // Prevent ORIGIN_OFFLINE prerenders from being destroyed on location.href
   // change, since the history is never merged for offline prerenders. Also
   // avoid adding aliases as they may potentially mark other valid requests to
@@ -597,13 +618,13 @@
     return;
   }
 
-  // Add each redirect as an alias. |params.url| is included in
-  // |params.redirects|.
+  // Add each redirect as an alias. |navigation_handle->GetURL()| is included in
+  // |navigation_handle->GetRedirectChain()|.
   //
   // TODO(davidben): We do not correctly patch up history for renderer-initated
   // navigations which add history entries. http://crbug.com/305660.
-  for (size_t i = 0; i < params.redirects.size(); i++) {
-    if (!AddAliasURL(params.redirects[i]))
+  for (const auto& redirect : navigation_handle->GetRedirectChain()) {
+    if (!AddAliasURL(redirect))
       return;
   }
 }
diff --git a/chrome/browser/prerender/prerender_contents.h b/chrome/browser/prerender/prerender_contents.h
index 3d2a82c..1926ce3 100644
--- a/chrome/browser/prerender/prerender_contents.h
+++ b/chrome/browser/prerender/prerender_contents.h
@@ -170,15 +170,12 @@
   void DidStopLoading() override;
   void DocumentLoadedInFrame(
       content::RenderFrameHost* render_frame_host) override;
-  void DidStartProvisionalLoadForFrame(
-      content::RenderFrameHost* render_frame_host,
-      const GURL& validated_url,
-      bool is_error_page) override;
+  void DidStartNavigation(
+      content::NavigationHandle* navigation_handle) override;
   void DidFinishLoad(content::RenderFrameHost* render_frame_host,
                      const GURL& validated_url) override;
-  void DidNavigateMainFrame(
-      const content::LoadCommittedDetails& details,
-      const content::FrameNavigateParams& params) override;
+  void DidFinishNavigation(
+      content::NavigationHandle* navigation_handle) override;
   void DidGetRedirectForResourceRequest(
       const content::ResourceRedirectDetails& details) override;
 
diff --git a/chrome/browser/resources/settings/certificate_manager_page/certificate_password_decryption_dialog.html b/chrome/browser/resources/settings/certificate_manager_page/certificate_password_decryption_dialog.html
index 1875cdb1..5d36e7e1 100644
--- a/chrome/browser/resources/settings/certificate_manager_page/certificate_password_decryption_dialog.html
+++ b/chrome/browser/resources/settings/certificate_manager_page/certificate_password_decryption_dialog.html
@@ -14,7 +14,8 @@
       <div class="body">
         <paper-input type="password" id="password"
             label="$i18n{certificateManagerPassword}"
-            value="{{password_}}"></paper-input>
+            value="{{password_}}" on-keypress="onKeypress_">
+        </paper-input>
       </div>
       <div class="button-container">
         <paper-button class="cancel-button" on-tap="onCancelTap_">
diff --git a/chrome/browser/resources/settings/certificate_manager_page/certificate_password_decryption_dialog.js b/chrome/browser/resources/settings/certificate_manager_page/certificate_password_decryption_dialog.js
index 82b7940..6232fc2d 100644
--- a/chrome/browser/resources/settings/certificate_manager_page/certificate_password_decryption_dialog.js
+++ b/chrome/browser/resources/settings/certificate_manager_page/certificate_password_decryption_dialog.js
@@ -48,4 +48,13 @@
               this.fire('certificates-error', error);
             }.bind(this));
   },
+
+  /**
+   * @param {!KeyboardEvent} e
+   * @private
+   */
+  onKeypress_: function(e) {
+    if (e.key == 'Enter' && !this.$.ok.disabled)
+      this.onOkTap_();
+  },
 });
diff --git a/chrome/browser/resources/settings/certificate_manager_page/certificate_password_encryption_dialog.html b/chrome/browser/resources/settings/certificate_manager_page/certificate_password_encryption_dialog.html
index 947879e..c4489fd 100644
--- a/chrome/browser/resources/settings/certificate_manager_page/certificate_password_encryption_dialog.html
+++ b/chrome/browser/resources/settings/certificate_manager_page/certificate_password_encryption_dialog.html
@@ -17,7 +17,7 @@
       <div class="title">$i18n{certificateManagerEncryptPasswordTitle}</div>
       <div class="body">
         <div>$i18n{certificateManagerEncryptPasswordDescription}</div>
-        <div class="password-buttons">
+        <div class="password-buttons" on-keypress="onKeypress_">
           <paper-input type="password" value="{{password_}}" id="password"
               label="$i18n{certificateManagerPassword}"
               on-input="validate_"></paper-input>
diff --git a/chrome/browser/resources/settings/certificate_manager_page/certificate_password_encryption_dialog.js b/chrome/browser/resources/settings/certificate_manager_page/certificate_password_encryption_dialog.js
index 0a0bd08..dc64b96b 100644
--- a/chrome/browser/resources/settings/certificate_manager_page/certificate_password_encryption_dialog.js
+++ b/chrome/browser/resources/settings/certificate_manager_page/certificate_password_encryption_dialog.js
@@ -58,6 +58,15 @@
             }.bind(this));
   },
 
+  /**
+   * @param {!KeyboardEvent} e
+   * @private
+   */
+  onKeypress_: function(e) {
+    if (e.key == 'Enter' && !this.$.ok.disabled)
+      this.onOkTap_();
+  },
+
   /** @private */
   validate_: function() {
     var isValid = this.password_ != '' &&
diff --git a/chrome/browser/resources/settings/device_page/display.js b/chrome/browser/resources/settings/device_page/display.js
index 1a9a8c9..dfea430 100644
--- a/chrome/browser/resources/settings/device_page/display.js
+++ b/chrome/browser/resources/settings/device_page/display.js
@@ -296,8 +296,13 @@
       var display = this.displays[i];
       if (id != display.id)
         continue;
-      this.currentSelectedModeIndex_ = -1;
-      this.selectedDisplay = display;
+      if (this.selectedDisplay != display) {
+        // Set currentSelectedModeIndex_ to -1 so that getResolutionText_ does
+        // not flicker. selectedDisplayChanged will update selectedModeIndex_
+        // and currentSelectedModeIndex_ correctly.
+        this.currentSelectedModeIndex_ = -1;
+        this.selectedDisplay = display;
+      }
     }
   },
 
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.html b/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.html
index a235d6a..0b19bde 100644
--- a/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.html
+++ b/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.html
@@ -11,9 +11,8 @@
     <dialog is="cr-dialog" id="dialog">
       <div class="title">[[dialogTitle_]]</div>
       <div class="body">
-        <paper-input always-float-label id="url"
-            label="$i18n{onStartupSiteUrl}"
-            value="{{url_}}" on-input="validate_">
+        <paper-input always-float-label id="url" label="$i18n{onStartupSiteUrl}"
+            value="{{url_}}" on-input="validate_" on-keypress="onKeypress_">
         </paper-input>
       </div>
       <div class="button-container">
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js b/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js
index c3b619cd..779516e8 100644
--- a/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js
+++ b/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js
@@ -67,6 +67,15 @@
     }.bind(this));
   },
 
+  /**
+   * @param {!KeyboardEvent} e
+   * @private
+   */
+  onKeypress_: function(e) {
+    if (e.key == 'Enter' && !this.$.actionButton.disabled)
+      this.onActionButtonTap_();
+  },
+
   /** @private */
   validate_: function() {
     this.browserProxy_.validateStartupPage(this.url_).then(function(isValid) {
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html
index f0f28d98..e7ef19b 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_page.html
+++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -216,6 +216,8 @@
           <button class="icon-help subpage-title-extra"
               is="paper-icon-button-light" on-tap="onHelpTap_"></button>
           <category-default-setting
+              toggle-off-label="$i18n{siteSettingsAutoDownloadBlock}"
+              toggle-on-label="$i18n{siteSettingsAutoDownloadAskRecommended}"
               category="{{ContentSettingsTypes.AUTOMATIC_DOWNLOADS}}">
           </category-default-setting>
           <category-setting-exceptions
@@ -228,6 +230,9 @@
           <button class="icon-help subpage-title-extra"
               is="paper-icon-button-light" on-tap="onHelpTap_"></button>
           <category-default-setting
+              toggle-off-label="$i18n{siteSettingsBackgroundSyncBlocked}"
+              toggle-on-label=
+                  "$i18n{siteSettingsAllowRecentlyClosedSitesRecommended}"
               category="{{ContentSettingsTypes.BACKGROUND_SYNC}}">
           </category-default-setting>
           <category-setting-exceptions
@@ -240,7 +245,10 @@
           <button class="icon-help subpage-title-extra"
               is="paper-icon-button-light" on-tap="onHelpTap_"></button>
           <media-picker type="camera"></media-picker>
-          <category-default-setting category="{{ContentSettingsTypes.CAMERA}}">
+          <category-default-setting category="{{ContentSettingsTypes.CAMERA}}"
+              toggle-off-label="$i18n{siteSettingsBlocked}"
+              toggle-on-label=
+                  "$i18n{siteSettingsAskBeforeAccessingRecommended}">
           </category-default-setting>
           <category-setting-exceptions
               category="{{ContentSettingsTypes.CAMERA}}">
@@ -252,6 +260,8 @@
           <button class="icon-help subpage-title-extra"
               is="paper-icon-button-light" on-tap="onHelpTap_"></button>
           <category-default-setting category="{{ContentSettingsTypes.COOKIES}}"
+              toggle-off-label="$i18n{siteSettingsBlocked}"
+              toggle-on-label="$i18n{siteSettingsCookiesAllowedRecommended}"
               sub-option-label="$i18n{deleteDataPostSession}"
               sub-option-secondary=""><!-- To work with :empty. -->
           </category-default-setting>
@@ -272,7 +282,9 @@
         <settings-subpage page-title="$i18n{siteSettingsCategoryImages}">
           <button class="icon-help subpage-title-extra"
               is="paper-icon-button-light" on-tap="onHelpTap_"></button>
-          <category-default-setting category="{{ContentSettingsTypes.IMAGES}}">
+          <category-default-setting category="{{ContentSettingsTypes.IMAGES}}"
+              toggle-off-label="$i18n{siteSettingsDontShowImages}"
+              toggle-on-label="$i18n{siteSettingsShowAllRecommended}">
           </category-default-setting>
           <category-setting-exceptions
               category="{{ContentSettingsTypes.IMAGES}}">
@@ -284,6 +296,8 @@
           <button class="icon-help subpage-title-extra"
               is="paper-icon-button-light" on-tap="onHelpTap_"></button>
           <category-default-setting
+              toggle-off-label="$i18n{siteSettingsBlocked}"
+              toggle-on-label="$i18n{siteSettingsAskBeforeAccessingRecommended}"
               category="{{ContentSettingsTypes.GEOLOCATION}}">
           </category-default-setting>
           <category-setting-exceptions
@@ -293,7 +307,10 @@
       </template>
       <template is="dom-if" route-path="/handlers" no-search>
         <settings-subpage page-title="$i18n{siteSettingsCategoryHandlers}">
-          <protocol-handlers></protocol-handlers>
+          <protocol-handlers
+              toggle-off-label="$i18n{siteSettingsHandlersBlocked}"
+              toggle-on-label="$i18n{siteSettingsHandlersAskRecommended}">
+          </protocol-handlers>
         </settings-subpage>
       </template>
       <template is="dom-if" route-path="/content/zoomLevels" no-search>
@@ -311,6 +328,8 @@
           <button class="icon-help subpage-title-extra"
               is="paper-icon-button-light" on-tap="onHelpTap_"></button>
           <category-default-setting
+              toggle-off-label="$i18n{siteSettingsBlocked}"
+              toggle-on-label="$i18n{siteSettingsAllowedRecommended}"
               category="{{ContentSettingsTypes.JAVASCRIPT}}">
           </category-default-setting>
           <category-setting-exceptions
@@ -323,7 +342,10 @@
           <button class="icon-help subpage-title-extra"
               is="paper-icon-button-light" on-tap="onHelpTap_"></button>
           <media-picker type="mic"></media-picker>
-          <category-default-setting category="{{ContentSettingsTypes.MIC}}">
+          <category-default-setting category="{{ContentSettingsTypes.MIC}}"
+              toggle-off-label="$i18n{siteSettingsBlocked}"
+              toggle-on-label=
+                  "$i18n{siteSettingsAskBeforeAccessingRecommended}">
           </category-default-setting>
           <category-setting-exceptions category="{{ContentSettingsTypes.MIC}}">
           </category-setting-exceptions>
@@ -334,6 +356,8 @@
           <button class="icon-help subpage-title-extra"
               is="paper-icon-button-light" on-tap="onHelpTap_"></button>
           <category-default-setting
+              toggle-off-label="$i18n{siteSettingsBlocked}"
+              toggle-on-label="$i18n{siteSettingsAskBeforeSendingRecommended}"
               category="{{ContentSettingsTypes.NOTIFICATIONS}}">
           </category-default-setting>
           <category-setting-exceptions
@@ -346,6 +370,8 @@
           <button class="icon-help subpage-title-extra"
               is="paper-icon-button-light" on-tap="onHelpTap_"></button>
           <category-default-setting category="{{ContentSettingsTypes.PLUGINS}}"
+              toggle-off-label="$i18n{siteSettingsFlashBlock}"
+              toggle-on-label="$i18n{siteSettingsFlashAllow}"
               sub-option-label="$i18n{siteSettingsFlashAskBefore}"
               sub-option-secondary="$i18n{siteSettingsFlashAskBeforeSubtitle}">
           </category-default-setting>
@@ -367,7 +393,9 @@
         <settings-subpage page-title="$i18n{siteSettingsCategoryPopups}">
           <button class="icon-help subpage-title-extra"
               is="paper-icon-button-light" on-tap="onHelpTap_"></button>
-          <category-default-setting category="{{ContentSettingsTypes.POPUPS}}">
+          <category-default-setting category="{{ContentSettingsTypes.POPUPS}}"
+              toggle-off-label="$i18n{siteSettingsBlockedRecommended}"
+              toggle-on-label="$i18n{siteSettingsAllowed}">
           </category-default-setting>
           <category-setting-exceptions
               category="{{ContentSettingsTypes.POPUPS}}">
@@ -379,6 +407,9 @@
           <button class="icon-help subpage-title-extra"
               is="paper-icon-button-light" on-tap="onHelpTap_"></button>
           <category-default-setting
+              toggle-off-label="$i18n{siteSettingsUnsandboxedPluginsBlock}"
+              toggle-on-label=
+                  "$i18n{siteSettingsUnsandboxedPluginsAskRecommended}"
               category="{{ContentSettingsTypes.UNSANDBOXED_PLUGINS}}">
           </category-default-setting>
           <category-setting-exceptions
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html b/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html
index ab6345a..8461bb9e 100644
--- a/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html
+++ b/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.html
@@ -10,7 +10,7 @@
     <style include="settings-shared"></style>
     <dialog is="cr-dialog" id="dialog">
       <div class="title">[[dialogTitle_]]</div>
-      <div class="body">
+      <div class="body" on-keypress="onKeypress_">
         <paper-input always-float-label id="searchEngine"
             label="$i18n{searchEnginesSearchEngine}"
             error-message="$i18n{searchEnginesNotValid}"
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.js b/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.js
index bf275f9..76e1e35 100644
--- a/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.js
+++ b/chrome/browser/resources/settings/search_engines_page/search_engine_dialog.js
@@ -92,6 +92,15 @@
   },
 
   /**
+   * @param {!KeyboardEvent} e
+   * @private
+   */
+  onKeypress_: function(e) {
+    if (e.key == 'Enter' && !this.$.actionButton.disabled)
+      this.onActionButtonTap_();
+  },
+
+  /**
    * @param {!Event} event
    * @private
    */
diff --git a/chrome/browser/resources/settings/site_settings/category_default_setting.js b/chrome/browser/resources/settings/site_settings/category_default_setting.js
index d360ef9..4496d23e 100644
--- a/chrome/browser/resources/settings/site_settings/category_default_setting.js
+++ b/chrome/browser/resources/settings/site_settings/category_default_setting.js
@@ -46,6 +46,10 @@
         return /** @type {chrome.settingsPrivate.PrefObject} */({});
       },
     },
+
+    /* Labels for the toggle on/off positions. */
+    toggleOffLabel: String,
+    toggleOnLabel: String,
   },
 
   observers: [
@@ -190,8 +194,9 @@
                 setting == settings.PermissionValues.SESSION_ONLY) {
               setting = settings.PermissionValues.ALLOW;
             }
+            var categoryEnabled = setting != settings.PermissionValues.BLOCK;
             this.sliderDescription_ =
-                this.computeCategoryDesc(this.category, setting, true);
+                categoryEnabled ? this.toggleOnLabel : this.toggleOffLabel;
           }.bind(this));
   },
 });
diff --git a/chrome/browser/resources/settings/site_settings/protocol_handlers.js b/chrome/browser/resources/settings/site_settings/protocol_handlers.js
index 43572b8..5e1fc30 100644
--- a/chrome/browser/resources/settings/site_settings/protocol_handlers.js
+++ b/chrome/browser/resources/settings/site_settings/protocol_handlers.js
@@ -54,7 +54,11 @@
      * The targetted object for menu operations.
      * @private {?Object}
      */
-    actionMenuModel_: Object
+    actionMenuModel_: Object,
+
+    /* Labels for the toggle on/off positions. */
+    toggleOffLabel: String,
+    toggleOnLabel: String,
   },
 
   ready: function() {
@@ -73,10 +77,7 @@
    * @private
    */
   computeHandlersDescription_: function() {
-    var setting = this.categoryEnabled ?
-        settings.PermissionValues.ALLOW : settings.PermissionValues.BLOCK;
-    return this.computeCategoryDesc(
-        settings.ContentSettingsTypes.PROTOCOL_HANDLERS, setting, true);
+    return this.categoryEnabled ? this.toggleOnLabel : this.toggleOffLabel;
   },
 
   /**
diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui.js b/chrome/browser/resources/vr_shell/vr_shell_ui.js
index ab078f0a..ce1b792f 100644
--- a/chrome/browser/resources/vr_shell/vr_shell_ui.js
+++ b/chrome/browser/resources/vr_shell/vr_shell_ui.js
@@ -544,4 +544,4 @@
   };
 })();
 
-document.addEventListener('DOMContentLoaded', vrShellUi.initialize);
+window.addEventListener('load', vrShellUi.initialize);
diff --git a/chrome/browser/resources/welcome/win10/default-large.webp b/chrome/browser/resources/welcome/win10/default-large.webp
new file mode 100644
index 0000000..cb55e122
--- /dev/null
+++ b/chrome/browser/resources/welcome/win10/default-large.webp
Binary files differ
diff --git a/chrome/browser/resources/welcome/win10/default-small.webp b/chrome/browser/resources/welcome/win10/default-small.webp
new file mode 100644
index 0000000..9a1345ad
--- /dev/null
+++ b/chrome/browser/resources/welcome/win10/default-small.webp
Binary files differ
diff --git a/chrome/browser/resources/welcome/win10/inline.css b/chrome/browser/resources/welcome/win10/inline.css
index 215ded8b..6eb9d5d 100644
--- a/chrome/browser/resources/welcome/win10/inline.css
+++ b/chrome/browser/resources/welcome/win10/inline.css
@@ -170,52 +170,47 @@
   width: 64vw;
 }
 
-#screenshot-image--default {
-  background: -webkit-image-set(
-    url(https://www.gstatic.com/chrome/login/win10/default-small.webp) 1x,
-    url(https://www.gstatic.com/chrome/login/win10/default-small@2x.webp) 2x);
+#default-image {
+  background: url(chrome://welcome-win10/default.webp);
   background-repeat: no-repeat;
   background-size: cover;
 }
 
-#screenshot-image--taskbar {
-  background: -webkit-image-set(
-    url(https://www.gstatic.com/chrome/login/win10/pin-small.webp) 1x,
-    url(https://www.gstatic.com/chrome/login/win10/pin-small@2x.webp) 2x);
+#taskbar-image {
+  background: url(chrome://welcome-win10/pin.webp);
   background-repeat: no-repeat;
   background-size: cover;
 }
 
-.screenshot-html-overlay {
+.screenshot-overlay {
   box-sizing: border-box;
-  font-size: 6px;
   line-height: 0;
   position: absolute;
 }
 
-#screenshot-html-overlay--browser {
-  left: 54.8%;
-  top: 53%;
+#browser-overlay {
+  left: 41%;
+  top: 81%;
 }
 
-#screenshot-html-overlay--edge {
-  left: 65%;
-  top: 63.5%;
+#edge-overlay {
+  left: 49%;
+  top: 88%;
 }
 
-#screenshot-html-overlay--taskbar {
+#taskbar-overlay {
   left: 31%;
   top: 73%;
 }
 
-#screenshot-html-overlay--taskbar div {
+#taskbar-overlay div {
   color: #ccc;
   font-family: Tahoma, Verdana, Segoe, sans-serif;
   font-weight: 500;
 }
 
-#screenshot-html-overlay--icon {
-  background-image: url(/logo-small.png);
+#icon-overlay {
+  background-image: url(chrome://welcome-win10/logo-small.png);
   background-size: cover;
   height: 8%;
   left: 46%;
@@ -223,17 +218,33 @@
   width: 6%;
 }
 
-/* This value is precisely set so that the text over the screenshot starts
+/* These values are precisely set so that the text over the screenshot starts
  * scaling at the same time the image starts scaling too. */
-@media (min-width: 312px) {
-  .screenshot-html-overlay {
+@media (max-width: 626px) {
+  #browser-overlay {
+    font-size: 1.28vw;
+  }
+
+  #edge-overlay {
+    font-size: 1.44vw;
+  }
+
+  #taskbar-overlay {
     font-size: 1.95vw;
   }
 }
 
-/* Font-size used when the screenshot exactly reaches its max size. */
+/* Font-sizes used when the screenshot exactly reaches its max size. */
 @media (min-width: 626px) {
-  .screenshot-html-overlay {
+  #browser-overlay {
+    font-size: 8px;
+  }
+
+  #edge-overlay {
+    font-size: 9px;
+  }
+
+  #taskbar-overlay {
     font-size: 12.2px;
   }
 }
diff --git a/chrome/browser/resources/welcome/win10/inline.html b/chrome/browser/resources/welcome/win10/inline.html
index 8a5bfa4b..52014ae 100644
--- a/chrome/browser/resources/welcome/win10/inline.html
+++ b/chrome/browser/resources/welcome/win10/inline.html
@@ -38,13 +38,11 @@
             </li>
             <li>
               <div>$i18nRaw{clickEdgeText}</div>
-              <div class="screenshot-image" id="screenshot-image--default">
-                <div class="screenshot-html-overlay"
-                    id="screenshot-html-overlay--browser">
+              <div class="screenshot-image" id="default-image">
+                <div class="screenshot-overlay" id="browser-overlay">
                   <div>$i18n{webBrowserLabel}</div>
                 </div>
-                <div class="screenshot-html-overlay"
-                    id="screenshot-html-overlay--edge">
+                <div class="screenshot-overlay" id="edge-overlay">
                   <div>$i18n{microsoftEdgeLabel}</div>
                 </div>
               </div>
@@ -63,13 +61,11 @@
               <li>$i18nRaw{rightClickText}</li>
               <li>
                 <div>$i18nRaw{pinInstructionText}</div>
-                <div class="screenshot-image" id="screenshot-image--taskbar">
-                  <div class="screenshot-html-overlay"
-                      id="screenshot-html-overlay--taskbar">
+                <div class="screenshot-image" id="taskbar-image">
+                  <div class="screenshot-overlay" id="taskbar-overlay">
                     <div>$i18n{pinToTaskbarLabel}</div>
                   </div>
-                  <div class="screenshot-html-overlay"
-                      id="screenshot-html-overlay--icon">
+                  <div class="screenshot-overlay" id="icon-overlay">
                   </div>
                 </div>
               </li>
diff --git a/chrome/browser/resources/welcome/win10/pin-large.webp b/chrome/browser/resources/welcome/win10/pin-large.webp
new file mode 100644
index 0000000..bf17795
--- /dev/null
+++ b/chrome/browser/resources/welcome/win10/pin-large.webp
Binary files differ
diff --git a/chrome/browser/resources/welcome/win10/pin-small.webp b/chrome/browser/resources/welcome/win10/pin-small.webp
new file mode 100644
index 0000000..a528175
--- /dev/null
+++ b/chrome/browser/resources/welcome/win10/pin-small.webp
Binary files differ
diff --git a/chrome/browser/resources/welcome/win10/sectioned.css b/chrome/browser/resources/welcome/win10/sectioned.css
index 77ec6744..c37f446 100644
--- a/chrome/browser/resources/welcome/win10/sectioned.css
+++ b/chrome/browser/resources/welcome/win10/sectioned.css
@@ -192,52 +192,47 @@
   opacity: 0;
 }
 
-#screenshot-image--default {
-  background: -webkit-image-set(
-    url(https://www.gstatic.com/chrome/login/win10/default-large.webp) 1x,
-    url(https://www.gstatic.com/chrome/login/win10/default-large@2x.webp) 2x);
+#default-image {
+  background: url(chrome://welcome-win10/default.webp);
   background-repeat: no-repeat;
   background-size: cover;
 }
 
-#screenshot-image--taskbar {
-  background: -webkit-image-set(
-    url(https://www.gstatic.com/chrome/login/win10/pin-large.webp) 1x,
-    url(https://www.gstatic.com/chrome/login/win10/pin-large@2x.webp) 2x);
+#taskbar-image {
+  background: url(chrome://welcome-win10/pin.webp);
   background-repeat: no-repeat;
   background-size: cover;
 }
 
-.screenshot-html-overlay {
+.screenshot-overlay {
   box-sizing: border-box;
-  font-size: 7px;
   line-height: 0;
   position: absolute;
 }
 
-#screenshot-html-overlay--browser {
-  left: 35.8%;
-  top: 75.8%;
+#browser-overlay {
+  left: 42.5%;
+  top: 76%;
 }
 
-#screenshot-html-overlay--edge {
-  left: 41.5%;
-  top: 82.4%;
+#edge-overlay {
+  left: 50%;
+  top: 84%;
 }
 
-#screenshot-html-overlay--taskbar {
+#taskbar-overlay {
   left: 62.2%;
   top: 81.5%;
 }
 
-#screenshot-html-overlay--taskbar div {
+#taskbar-overlay div {
   color: #ccc;
   font-family: Tahoma, Verdana, Segoe, sans-serif;
   font-weight: 500;
 }
 
-#screenshot-html-overlay--icon {
-  background-image: url(/logo-small.png);
+#icon-overlay {
+  background-image: url(chrome://welcome-win10/logo-small.png);
   background-size: cover;
   height: 5.8%;
   left: 70.60%;
@@ -245,21 +240,53 @@
   width: 3.5%;
 }
 
-/* This value is precisely set so that the text over the screenshot starts
+
+/* These values are precisely set so that the text over the screenshot starts
  * scaling at the same time the image starts scaling too. */
 @media (min-width: 520px) {
-  .screenshot-html-overlay {
+  #browser-overlay {
+    font-size: 1.8vw;
+  }
+
+  #edge-overlay {
+    font-size: 2.05vw;
+  }
+
+  #taskbar-overlay {
     font-size: 1.35vw;
   }
 }
 
-/* Font-size used when the screenshot exactly reaches its max size. */
+/* Font-sizes used when the screenshot exactly reaches its max size. */
 @media (min-width: 780px) {
-  .screenshot-html-overlay {
+  #browser-overlay {
+    font-size: 14px;
+  }
+
+  #edge-overlay {
+    font-size: 16px;
+  }
+
+  #taskbar-overlay {
     font-size: 10.5px;
   }
 }
 
+/* Font-sizes used when the screenshot exactly reaches its min size. */
+@media(max-width: 520px) {
+  #browser-overlay {
+    font-size: 9px;
+  }
+
+  #edge-overlay {
+    font-size: 10.5px;
+  }
+
+  #taskbar-overlay {
+    font-size: 7px;
+  }
+}
+
 @media (min-width: 1280px) {
   body {
     flex-direction: row;
diff --git a/chrome/browser/resources/welcome/win10/sectioned.html b/chrome/browser/resources/welcome/win10/sectioned.html
index d148da2..f03ef12 100644
--- a/chrome/browser/resources/welcome/win10/sectioned.html
+++ b/chrome/browser/resources/welcome/win10/sectioned.html
@@ -62,23 +62,23 @@
     </div>
     <div class="bg">
       <div class="screenshots">
-        <div class="screenshot-image" id="screenshot-image--default">
-          <div class="screenshot-html-overlay"
-              id="screenshot-html-overlay--browser">
+        <div class="screenshot-image" id="default-image">
+          <div class="screenshot-overlay"
+              id="browser-overlay">
             <div>$i18n{webBrowserLabel}</div>
           </div>
-          <div class="screenshot-html-overlay"
-              id="screenshot-html-overlay--edge">
+          <div class="screenshot-overlay"
+              id="edge-overlay">
             <div>$i18n{microsoftEdgeLabel}</div>
           </div>
         </div>
-        <div class="screenshot-image hidden" id="screenshot-image--taskbar">
-          <div class="screenshot-html-overlay"
-              id="screenshot-html-overlay--taskbar">
+        <div class="screenshot-image hidden" id="taskbar-image">
+          <div class="screenshot-overlay"
+              id="taskbar-overlay">
             <div>$i18n{pinToTaskbarLabel}</div>
           </div>
-          <div class="screenshot-html-overlay"
-              id="screenshot-html-overlay--icon">
+          <div class="screenshot-overlay"
+              id="icon-overlay">
           </div>
         </div>
       </div>
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc
index 3071414c2..af21ad7 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -39,7 +39,6 @@
 #include "components/safe_browsing/common/safebrowsing_constants.h"
 #include "components/safe_browsing/common/safebrowsing_switches.h"
 #include "components/safe_browsing_db/database_manager.h"
-#include "components/safe_browsing_db/safe_browsing_prefs.h"
 #include "components/safe_browsing_db/v4_feature_list.h"
 #include "components/safe_browsing_db/v4_get_hash_protocol_manager.h"
 #include "components/safe_browsing_db/v4_local_database_manager.h"
@@ -297,6 +296,7 @@
 
 SafeBrowsingService::SafeBrowsingService()
     : services_delegate_(ServicesDelegate::Create(this)),
+      estimated_extended_reporting_by_prefs_(SBER_LEVEL_OFF),
       enabled_(false),
       enabled_by_prefs_(false),
       enabled_v4_only_(safe_browsing::V4FeatureList::IsV4OnlyEnabled()) {}
@@ -671,9 +671,9 @@
   std::unique_ptr<PrefChangeRegistrar> registrar =
       base::MakeUnique<PrefChangeRegistrar>();
   registrar->Init(pref_service);
-  registrar->Add(prefs::kSafeBrowsingEnabled,
-                 base::Bind(&SafeBrowsingService::RefreshState,
-                            base::Unretained(this)));
+  registrar->Add(
+      prefs::kSafeBrowsingEnabled,
+      base::Bind(&SafeBrowsingService::RefreshState, base::Unretained(this)));
   // ClientSideDetectionService will need to be refresh the models
   // renderers have if extended-reporting changes.
   registrar->Add(
@@ -721,24 +721,28 @@
 void SafeBrowsingService::RefreshState() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // Check if any profile requires the service to be active.
-  bool enable = false;
+  enabled_by_prefs_ = false;
+  estimated_extended_reporting_by_prefs_ = SBER_LEVEL_OFF;
   for (const auto& pref : prefs_map_) {
     if (pref.first->GetBoolean(prefs::kSafeBrowsingEnabled)) {
-      enable = true;
-      break;
+      enabled_by_prefs_ = true;
+      ExtendedReportingLevel erl =
+          safe_browsing::GetExtendedReportingLevel(*pref.first);
+      if (erl != SBER_LEVEL_OFF) {
+        estimated_extended_reporting_by_prefs_ = erl;
+        break;
+      }
     }
   }
 
-  enabled_by_prefs_ = enable;
-
-  if (enable)
+  if (enabled_by_prefs_)
     Start();
   else
     Stop(false);
 
   state_callback_list_.Notify();
 
-  services_delegate_->RefreshState(enable);
+  services_delegate_->RefreshState(enabled_by_prefs_);
 }
 
 void SafeBrowsingService::SendSerializedDownloadReport(
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.h b/chrome/browser/safe_browsing/safe_browsing_service.h
index 07b97413..d1d35549 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.h
+++ b/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -20,6 +20,7 @@
 #include "base/observer_list.h"
 #include "base/sequenced_task_runner_helpers.h"
 #include "chrome/browser/safe_browsing/services_delegate.h"
+#include "components/safe_browsing_db/safe_browsing_prefs.h"
 #include "components/safe_browsing_db/util.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_observer.h"
@@ -100,6 +101,15 @@
   // Returns the client_name field for both V3 and V4 protocol manager configs.
   std::string GetProtocolConfigClientName() const;
 
+  // NOTE(vakh): This is not the most reliable way to find out if extended
+  // reporting has been enabled. That's why it starts with estimated_. It
+  // returns true if any of the profiles have extended reporting enabled. It may
+  // be called on any thread. That can lead to a race condition, but that's
+  // acceptable.
+  ExtendedReportingLevel estimated_extended_reporting_by_prefs() const {
+    return estimated_extended_reporting_by_prefs_;
+  }
+
   // Get current enabled status. Must be called on IO thread.
   bool enabled() const {
     DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
@@ -274,6 +284,10 @@
   // Provides phishing and malware statistics. Accessed on IO thread.
   std::unique_ptr<SafeBrowsingPingManager> ping_manager_;
 
+  // Whether SafeBrowsing Extended Reporting is enabled by the current set of
+  // profiles. Updated on the UI thread.
+  ExtendedReportingLevel estimated_extended_reporting_by_prefs_;
+
   // Whether the service is running. 'enabled_' is used by SafeBrowsingService
   // on the IO thread during normal operations.
   bool enabled_;
diff --git a/chrome/browser/safe_browsing/services_delegate_impl.cc b/chrome/browser/safe_browsing/services_delegate_impl.cc
index e239d89..d18b40e 100644
--- a/chrome/browser/safe_browsing/services_delegate_impl.cc
+++ b/chrome/browser/safe_browsing/services_delegate_impl.cc
@@ -54,6 +54,11 @@
 #endif  // defined(SAFE_BROWSING_CSD)
 }
 
+ExtendedReportingLevel
+ServicesDelegateImpl::GetEstimatedExtendedReportingLevel() const {
+  return safe_browsing_service_->estimated_extended_reporting_by_prefs();
+}
+
 const scoped_refptr<SafeBrowsingDatabaseManager>&
 ServicesDelegateImpl::v4_local_database_manager() const {
   return v4_local_database_manager_;
@@ -62,8 +67,10 @@
 void ServicesDelegateImpl::Initialize() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  v4_local_database_manager_ =
-      V4LocalDatabaseManager::Create(SafeBrowsingService::GetBaseFilename());
+  v4_local_database_manager_ = V4LocalDatabaseManager::Create(
+      SafeBrowsingService::GetBaseFilename(),
+      base::Bind(&ServicesDelegateImpl::GetEstimatedExtendedReportingLevel,
+                 base::Unretained(this)));
 
   download_service_.reset(
       (services_creator_ &&
diff --git a/chrome/browser/safe_browsing/services_delegate_impl.h b/chrome/browser/safe_browsing/services_delegate_impl.h
index e975b83..acd95d79 100644
--- a/chrome/browser/safe_browsing/services_delegate_impl.h
+++ b/chrome/browser/safe_browsing/services_delegate_impl.h
@@ -51,6 +51,14 @@
     const V4ProtocolConfig& v4_config) override;
   void StopOnIOThread(bool shutdown) override;
 
+  // Reports the current extended reporting level. Note that this is an
+  // estimation and may not always be correct. It is possible that the
+  // estimation finds both Scout and legacy extended reporting to be enabled.
+  // This can happen, for instance, if one profile has Scout enabled and another
+  // has legacy extended reporting enabled. In such a case, this method reports
+  // LEGACY as the current level.
+  ExtendedReportingLevel GetEstimatedExtendedReportingLevel() const;
+
   DownloadProtectionService* CreateDownloadProtectionService();
   IncidentReportingService* CreateIncidentReportingService();
   ResourceRequestDetector* CreateResourceRequestDetector();
diff --git a/chrome/browser/site_per_process_interactive_browsertest.cc b/chrome/browser/site_per_process_interactive_browsertest.cc
index 79fe4f6..7481c0d8 100644
--- a/chrome/browser/site_per_process_interactive_browsertest.cc
+++ b/chrome/browser/site_per_process_interactive_browsertest.cc
@@ -4,6 +4,7 @@
 
 #include "base/command_line.h"
 #include "base/strings/string_number_conversions.h"
+#include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h"
@@ -11,13 +12,19 @@
 #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"
+#include "components/guest_view/browser/guest_view_manager_delegate.h"
+#include "components/guest_view/browser/test_guest_view_manager.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_widget_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "content/public/test/test_utils.h"
+#include "extensions/browser/api/extensions_api_client.h"
+#include "extensions/common/constants.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "ui/display/display.h"
@@ -785,3 +792,135 @@
                             "removeChild(document.querySelector('iframe'))"));
   EXPECT_FALSE(main_frame->GetView()->IsMouseLocked());
 }
+
+// Base test class for interactive tests which load and test PDF files.
+class SitePerProcessInteractivePDFTest
+    : public SitePerProcessInteractiveBrowserTest {
+ public:
+  SitePerProcessInteractivePDFTest() : test_guest_view_manager_(nullptr) {}
+  ~SitePerProcessInteractivePDFTest() override {}
+
+  void SetUpOnMainThread() override {
+    SitePerProcessInteractiveBrowserTest::SetUpOnMainThread();
+    guest_view::GuestViewManager::set_factory_for_testing(&factory_);
+    test_guest_view_manager_ = static_cast<guest_view::TestGuestViewManager*>(
+        guest_view::GuestViewManager::CreateWithDelegate(
+            browser()->profile(),
+            extensions::ExtensionsAPIClient::Get()
+                ->CreateGuestViewManagerDelegate(browser()->profile())));
+  }
+
+ protected:
+  guest_view::TestGuestViewManager* test_guest_view_manager() const {
+    return test_guest_view_manager_;
+  }
+
+ private:
+  guest_view::TestGuestViewManagerFactory factory_;
+  guest_view::TestGuestViewManager* test_guest_view_manager_;
+
+  DISALLOW_COPY_AND_ASSIGN(SitePerProcessInteractivePDFTest);
+};
+
+// This class observes a WebContents for a navigation to an extension scheme to
+// finish.
+class NavigationToExtensionSchemeObserver
+    : public content::WebContentsObserver {
+ public:
+  explicit NavigationToExtensionSchemeObserver(content::WebContents* contents)
+      : content::WebContentsObserver(contents),
+        extension_loaded_(contents->GetLastCommittedURL().SchemeIs(
+            extensions::kExtensionScheme)) {}
+
+  void Wait() {
+    if (extension_loaded_)
+      return;
+    message_loop_runner_ = new content::MessageLoopRunner();
+    message_loop_runner_->Run();
+  }
+
+ private:
+  void DidFinishNavigation(content::NavigationHandle* handle) override {
+    if (!handle->GetURL().SchemeIs(extensions::kExtensionScheme) ||
+        !handle->HasCommitted() || handle->IsErrorPage())
+      return;
+    extension_loaded_ = true;
+    message_loop_runner_->Quit();
+  }
+
+  bool extension_loaded_;
+  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
+
+  DISALLOW_COPY_AND_ASSIGN(NavigationToExtensionSchemeObserver);
+};
+
+// This test loads a PDF inside an OOPIF and then verifies that context menu
+// shows up at the correct position.
+IN_PROC_BROWSER_TEST_F(SitePerProcessInteractivePDFTest,
+                       ContextMenuPositionForEmbeddedPDFInCrossOriginFrame) {
+  // Navigate to a page with an <iframe>.
+  GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
+  ui_test_utils::NavigateToURL(browser(), main_url);
+
+  // Initially, no guests are created.
+  EXPECT_EQ(0U, test_guest_view_manager()->num_guests_created());
+
+  content::WebContents* active_web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  // Change the position of the <iframe> inside the page.
+  EXPECT_TRUE(ExecuteScript(active_web_contents,
+                            "document.querySelector('iframe').style ="
+                            " 'margin-left: 100px; margin-top: 100px;';"));
+
+  // Navigate subframe to a cross-site page with an embedded PDF.
+  GURL frame_url =
+      embedded_test_server()->GetURL("b.com", "/page_with_embedded_pdf.html");
+
+  // Ensure the page finishes loading without crashing.
+  EXPECT_TRUE(NavigateIframeToURL(active_web_contents, "test", frame_url));
+
+  // Wait until the guest contents for PDF is created.
+  content::WebContents* guest_contents =
+      test_guest_view_manager()->WaitForSingleGuestCreated();
+
+  // Observe navigations in guest to find out when navigation to the (PDF)
+  // extension commits. It will be used as an indicator that BrowserPlugin
+  // has attached.
+  NavigationToExtensionSchemeObserver navigation_observer(guest_contents);
+
+  // Before sending the mouse clicks, we need to make sure the BrowserPlugin has
+  // attached, which happens before navigating the guest to the PDF extension.
+  // When attached, the window rects are updated and the context menu position
+  // can be properly calculated.
+  navigation_observer.Wait();
+
+  content::RenderWidgetHostView* child_view =
+      ChildFrameAt(active_web_contents->GetMainFrame(), 0)->GetView();
+
+  ContextMenuWaiter menu_waiter(content::NotificationService::AllSources());
+
+  // Declaring a lambda to send a right-button mouse event to the embedder
+  // frame.
+  auto send_right_mouse_event = [](content::RenderWidgetHost* host, int x,
+                                   int y, blink::WebInputEvent::Type type) {
+    blink::WebMouseEvent event;
+    event.x = x;
+    event.y = y;
+    event.button = blink::WebMouseEvent::Button::Right;
+    event.setType(type);
+    host->ForwardMouseEvent(event);
+  };
+
+  send_right_mouse_event(child_view->GetRenderWidgetHost(), 10, 20,
+                         blink::WebInputEvent::MouseDown);
+  send_right_mouse_event(child_view->GetRenderWidgetHost(), 10, 20,
+                         blink::WebInputEvent::MouseUp);
+  menu_waiter.WaitForMenuOpenAndClose();
+
+  gfx::Point point_in_root_window =
+      child_view->TransformPointToRootCoordSpace(gfx::Point(10, 20));
+
+  EXPECT_EQ(point_in_root_window.x(), menu_waiter.params().x);
+  EXPECT_EQ(point_in_root_window.y(), menu_waiter.params().y);
+}
diff --git a/chrome/browser/sync/sessions/sessions_sync_manager_unittest.cc b/chrome/browser/sync/sessions/sessions_sync_manager_unittest.cc
index 886c2a4..0980bba 100644
--- a/chrome/browser/sync/sessions/sessions_sync_manager_unittest.cc
+++ b/chrome/browser/sync/sessions/sessions_sync_manager_unittest.cc
@@ -48,6 +48,17 @@
 
 namespace {
 
+const char kFoo1[] = "http://foo1/";
+const char kFoo2[] = "http://foo2/";
+const char kBar1[] = "http://bar1/";
+const char kBar2[] = "http://bar2/";
+const char kBaz1[] = "http://baz1/";
+const char kBaz2[] = "http://baz2/";
+
+std::string TabNodeIdToTag(const std::string& machine_tag, int tab_node_id) {
+  return base::StringPrintf("%s %d", machine_tag.c_str(), tab_node_id);
+}
+
 class SessionNotificationObserver {
  public:
   SessionNotificationObserver()
@@ -128,7 +139,7 @@
   std::map<int, SyncedTabDelegate*> tab_overrides_;
   std::map<int, SessionID::id_type> tab_id_overrides_;
   const SyncedWindowDelegate* const wrapped_;
-  SessionID::id_type session_id_override_ = -1;
+  SessionID::id_type session_id_override_ = TabNodePool::kInvalidTabID;
 };
 
 class TestSyncedWindowDelegatesGetter : public SyncedWindowDelegatesGetter {
@@ -399,6 +410,10 @@
     return sessions_client_shim_.get();
   }
 
+  TabNodePool* GetTabPool() {
+    return &manager()->session_tracker_.local_tab_pool_;
+  }
+
   syncer::SyncPrefs* sync_prefs() { return sync_prefs_.get(); }
 
   SyncedWindowDelegatesGetter* get_synced_window_getter() {
@@ -502,40 +517,32 @@
 
 namespace {
 
+// A SyncedTabDelegate fake for testing. It simulates a normal
+// SyncedTabDelegate with a proper WebContents. For a SyncedTabDelegate without
+// a WebContents, see PlaceholderTabDelegate below.
 class SyncedTabDelegateFake : public SyncedTabDelegate {
  public:
-  SyncedTabDelegateFake()
-      : current_entry_index_(0), is_supervised_(false), sync_id_(-1) {}
+  SyncedTabDelegateFake() {}
   ~SyncedTabDelegateFake() override {}
 
+  // SyncedTabDelegate overrides.
   bool IsInitialBlankNavigation() const override {
     // This differs from NavigationControllerImpl, which has an initial blank
     // NavigationEntry.
     return GetEntryCount() == 0;
   }
   int GetCurrentEntryIndex() const override { return current_entry_index_; }
-  void set_current_entry_index(int i) {
-    current_entry_index_ = i;
-  }
-
-  void AppendEntry(std::unique_ptr<content::NavigationEntry> entry) {
-    entries_.push_back(std::move(entry));
-  }
-
   GURL GetVirtualURLAtIndex(int i) const override {
     if (static_cast<size_t>(i) >= entries_.size())
       return GURL();
     return entries_[i]->GetVirtualURL();
   }
-
   GURL GetFaviconURLAtIndex(int i) const override { return GURL(); }
-
   ui::PageTransition GetTransitionAtIndex(int i) const override {
     if (static_cast<size_t>(i) >= entries_.size())
       return ui::PAGE_TRANSITION_LINK;
     return entries_[i]->GetTransitionType();
   }
-
   void GetSerializedNavigationAtIndex(
       int i,
       sessions::SerializedNavigationEntry* serialized_entry) const override {
@@ -545,17 +552,9 @@
         sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
             i, *entries_[i]);
   }
-
   int GetEntryCount() const override { return entries_.size(); }
-
-  SessionID::id_type GetWindowId() const override {
-    return SessionID::id_type();
-  }
-
-  SessionID::id_type GetSessionId() const override {
-    return SessionID::id_type();
-  }
-
+  SessionID::id_type GetWindowId() const override { return window_id_; }
+  SessionID::id_type GetSessionId() const override { return tab_id_; }
   bool IsBeingDestroyed() const override { return false; }
   std::string GetExtensionAppId() const override { return std::string(); }
   bool ProfileIsSupervised() const override { return is_supervised_; }
@@ -564,6 +563,23 @@
   GetBlockedNavigations() const override {
     return &blocked_navigations_;
   }
+  bool IsPlaceholderTab() const override { return false; }
+  int GetSyncId() const override { return sync_id_; }
+  void SetSyncId(int sync_id) override { sync_id_ = sync_id; }
+  bool ShouldSync(SyncSessionsClient* sessions_client) override {
+    return false;
+  }
+
+  void AppendEntry(std::unique_ptr<content::NavigationEntry> entry) {
+    entries_.push_back(std::move(entry));
+  }
+
+  void set_current_entry_index(int i) { current_entry_index_ = i; }
+
+  void SetWindowId(SessionID::id_type window_id) { window_id_ = window_id; }
+
+  void SetSessionId(SessionID::id_type id) { tab_id_ = id; }
+
   void set_blocked_navigations(
       std::vector<const content::NavigationEntry*>* navs) {
     for (auto* entry : *navs) {
@@ -574,31 +590,101 @@
       blocked_navigations_.push_back(std::move(serialized_entry));
     }
   }
-  bool IsPlaceholderTab() const override { return true; }
-
-  // Session sync related methods.
-  int GetSyncId() const override { return sync_id_; }
-  void SetSyncId(int sync_id) override { sync_id_ = sync_id; }
-
-  bool ShouldSync(SyncSessionsClient* sessions_client) override {
-    return false;
-  }
 
   void reset() {
     current_entry_index_ = 0;
-    sync_id_ = -1;
+    sync_id_ = TabNodePool::kInvalidTabNodeID;
     entries_.clear();
   }
 
  private:
-  int current_entry_index_;
-  bool is_supervised_;
-  int sync_id_;
+  int current_entry_index_ = 0;
+  bool is_supervised_ = false;
+  int sync_id_ = -1;
+  SessionID::id_type tab_id_ = 0;
+  SessionID::id_type window_id_ = 0;
   std::vector<std::unique_ptr<const sessions::SerializedNavigationEntry>>
       blocked_navigations_;
   std::vector<std::unique_ptr<content::NavigationEntry>> entries_;
 };
 
+// A placeholder delegate. These delegates have no WebContents, simulating a tab
+// that has been restored without bringing its state fully into memory (for
+// example on Android), or where the tab's contents have been evicted from
+// memory. See SyncedTabDelegate::IsPlaceHolderTab for more info.
+class PlaceholderTabDelegate : public SyncedTabDelegate {
+ public:
+  PlaceholderTabDelegate(SessionID::id_type session_id, int sync_id)
+      : session_id_(session_id), sync_id_(sync_id) {}
+  ~PlaceholderTabDelegate() override {}
+
+  // SyncedTabDelegate overrides.
+  SessionID::id_type GetSessionId() const override { return session_id_; }
+  int GetSyncId() const override { return sync_id_; }
+  void SetSyncId(int sync_id) override { sync_id_ = sync_id; }
+  bool IsPlaceholderTab() const override { return true; }
+
+  // Everything else is invalid to invoke as it depends on a valid WebContents.
+  SessionID::id_type GetWindowId() const override {
+    NOTREACHED();
+    return 0;
+  }
+  bool IsBeingDestroyed() const override {
+    NOTREACHED();
+    return false;
+  }
+  std::string GetExtensionAppId() const override {
+    NOTREACHED();
+    return "";
+  }
+  bool IsInitialBlankNavigation() const override {
+    NOTREACHED();
+    return false;
+  }
+  int GetCurrentEntryIndex() const override {
+    NOTREACHED();
+    return 0;
+  }
+  int GetEntryCount() const override {
+    NOTREACHED();
+    return 0;
+  }
+  GURL GetVirtualURLAtIndex(int i) const override {
+    NOTREACHED();
+    return GURL();
+  }
+  GURL GetFaviconURLAtIndex(int i) const override {
+    NOTREACHED();
+    return GURL();
+  }
+  ui::PageTransition GetTransitionAtIndex(int i) const override {
+    NOTREACHED();
+    return ui::PageTransition();
+  }
+  void GetSerializedNavigationAtIndex(
+      int i,
+      sessions::SerializedNavigationEntry* serialized_entry) const override {
+    NOTREACHED();
+  }
+  bool ProfileIsSupervised() const override {
+    NOTREACHED();
+    return false;
+  }
+  const std::vector<std::unique_ptr<const sessions::SerializedNavigationEntry>>*
+  GetBlockedNavigations() const override {
+    NOTREACHED();
+    return nullptr;
+  }
+  bool ShouldSync(SyncSessionsClient* sessions_client) override {
+    NOTREACHED();
+    return false;
+  }
+
+ private:
+  SessionID::id_type session_id_;
+  int sync_id_;
+};
+
 }  // namespace
 
 static const base::Time kTime0 = base::Time::FromInternalValue(100);
@@ -953,29 +1039,31 @@
 
 // Ensure model association associates the pre-existing tabs.
 TEST_F(SessionsSyncManagerTest, SwappedOutOnRestore) {
-  AddTab(browser(), GURL("http://foo1"));
-  NavigateAndCommitActiveTab(GURL("http://foo2"));
-  AddTab(browser(), GURL("http://bar1"));
-  NavigateAndCommitActiveTab(GURL("http://bar2"));
-  AddTab(browser(), GURL("http://baz1"));
-  NavigateAndCommitActiveTab(GURL("http://baz2"));
   const int kRestoredTabId = 1337;
   const int kNewTabId = 2468;
 
+  // AddTab inserts at index 0, so go in reverse order (tab 3 -> tab 1).
+  AddTab(browser(), GURL(kBaz1));
+  NavigateAndCommitActiveTab(GURL(kBaz2));
+  AddTab(browser(), GURL(kBar1));
+  NavigateAndCommitActiveTab(GURL(kBar2));
+  AddTab(browser(), GURL(kFoo1));
+  NavigateAndCommitActiveTab(GURL(kFoo2));
+
   syncer::SyncDataList in;
   syncer::SyncChangeList out;
   InitWithSyncDataTakeOutput(in, &out);
 
-  // Should be one header add, 3 tab add/update pairs, one header update.
-  ASSERT_EQ(8U, out.size());
+  // Should be one header add, 3 tab adds, one header update.
+  ASSERT_EQ(5U, out.size());
 
   // For input, we set up:
   // * one "normal" fully loaded tab
-  // * one "frozen" tab with no WebContents and a tab_id change
-  // * one "frozen" tab with no WebContents and no tab_id change
-  sync_pb::EntitySpecifics t0_entity = out[2].sync_data().GetSpecifics();
-  sync_pb::EntitySpecifics t1_entity = out[4].sync_data().GetSpecifics();
-  sync_pb::EntitySpecifics t2_entity = out[6].sync_data().GetSpecifics();
+  // * one placeholder tab with no WebContents and a tab_id change
+  // * one placeholder tab with no WebContents and no tab_id change
+  sync_pb::EntitySpecifics t0_entity = out[1].sync_data().GetSpecifics();
+  sync_pb::EntitySpecifics t1_entity = out[2].sync_data().GetSpecifics();
+  sync_pb::EntitySpecifics t2_entity = out[3].sync_data().GetSpecifics();
   t1_entity.mutable_session()->mutable_tab()->set_tab_id(kRestoredTabId);
   in.push_back(CreateRemoteData(t0_entity));
   in.push_back(CreateRemoteData(t1_entity));
@@ -986,9 +1074,8 @@
   const std::set<const SyncedWindowDelegate*>& windows =
       manager()->synced_window_delegates_getter()->GetSyncedWindowDelegates();
   ASSERT_EQ(1U, windows.size());
-  SyncedTabDelegateFake t1_override, t2_override;
-  t1_override.SetSyncId(1);  // No WebContents by default.
-  t2_override.SetSyncId(2);  // No WebContents by default.
+  PlaceholderTabDelegate t1_override(kNewTabId, 1);
+  PlaceholderTabDelegate t2_override(t2_entity.session().tab().tab_id(), 2);
   SyncedWindowDelegateOverride window_override(*windows.begin());
   window_override.OverrideTabAt(1, &t1_override, kNewTabId);
   window_override.OverrideTabAt(2, &t2_override,
@@ -1005,26 +1092,39 @@
       std::unique_ptr<syncer::SyncErrorFactory>(
           new syncer::SyncErrorFactoryMock()));
 
-  // There should be two changes, one for the fully associated tab, and
-  // one for the tab_id update to t1.  t2 shouldn't need to be updated.
-  ASSERT_EQ(2U, FilterOutLocalHeaderChanges(&out)->size());
+  // There should be three changes, one for the fully associated tab, and
+  // one each for the tab_id updates to t1 and t2.
+  ASSERT_EQ(3U, FilterOutLocalHeaderChanges(&out)->size());
   EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type());
+  EXPECT_EQ(kFoo2, out[0]
+                       .sync_data()
+                       .GetSpecifics()
+                       .session()
+                       .tab()
+                       .navigation(1)
+                       .virtual_url());
+
   EXPECT_EQ(SyncChange::ACTION_UPDATE, out[1].change_type());
   EXPECT_EQ(kNewTabId,
             out[1].sync_data().GetSpecifics().session().tab().tab_id());
+  EXPECT_EQ(kBar2, out[1]
+                       .sync_data()
+                       .GetSpecifics()
+                       .session()
+                       .tab()
+                       .navigation(1)
+                       .virtual_url());
 
-  // Verify TabLinks.
-  SessionsSyncManager::TabLinksMap tab_map = manager()->local_tab_map_;
-  ASSERT_EQ(3U, tab_map.size());
-  int t2_tab_id = t2_entity.session().tab().tab_id();
-  EXPECT_EQ(2, tab_map.find(t2_tab_id)->second->tab_node_id());
-  EXPECT_EQ(1, tab_map.find(kNewTabId)->second->tab_node_id());
-  int t0_tab_id = out[0].sync_data().GetSpecifics().session().tab().tab_id();
-  EXPECT_EQ(0, tab_map.find(t0_tab_id)->second->tab_node_id());
-  // TODO(tim): Once bug 337057 is fixed, we can issue an OnLocalTabModified
-  // from here (using an override similar to above) to return a new tab id
-  // and verify that we don't see any node creations in the SyncChangeProcessor
-  // (similar to how SessionsSyncManagerTest.OnLocalTabModified works.)
+  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[2].change_type());
+  EXPECT_EQ(t2_entity.session().tab().tab_id(),
+            out[2].sync_data().GetSpecifics().session().tab().tab_id());
+  EXPECT_EQ(kBaz2, out[2]
+                       .sync_data()
+                       .GetSpecifics()
+                       .session()
+                       .tab()
+                       .navigation(1)
+                       .virtual_url());
 }
 
 // Ensure model association updates the window ID for tabs whose window's ID has
@@ -1035,21 +1135,22 @@
   syncer::SyncChangeList out;
 
   // Set up one tab and start sync with it.
-  AddTab(browser(), GURL("http://foo1"));
-  NavigateAndCommitActiveTab(GURL("http://foo2"));
+  AddTab(browser(), GURL(kFoo1));
+  NavigateAndCommitActiveTab(GURL(kFoo2));
   InitWithSyncDataTakeOutput(in, &out);
 
-  // Should be one header add, 1 tab add/update pair, and one header update.
-  ASSERT_EQ(4U, out.size());
-  const sync_pb::EntitySpecifics t0_entity = out[2].sync_data().GetSpecifics();
+  // Should be one header add, 1 tab add, and one header update.
+  ASSERT_EQ(3U, out.size());
+  const sync_pb::EntitySpecifics t0_entity = out[1].sync_data().GetSpecifics();
+  ASSERT_TRUE(t0_entity.session().has_tab());
 
   in.push_back(CreateRemoteData(t0_entity));
   out.clear();
   manager()->StopSyncing(syncer::SESSIONS);
 
-  // SyncedTabDelegateFake is a placeholder (no WebContents) by default.
-  SyncedTabDelegateFake t0_override;
-  t0_override.SetSyncId(t0_entity.session().tab_node_id());
+  // Override the tab with a placeholder tab delegate.
+  PlaceholderTabDelegate t0_override(t0_entity.session().tab().tab_id(),
+                                     t0_entity.session().tab_node_id());
 
   // Set up the window override with the new window ID and placeholder tab.
   const std::set<const SyncedWindowDelegate*>& windows =
@@ -1078,6 +1179,64 @@
   EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type());
   EXPECT_EQ(kNewWindowId,
             out[0].sync_data().GetSpecifics().session().tab().window_id());
+  EXPECT_EQ(kFoo2, out[0]
+                       .sync_data()
+                       .GetSpecifics()
+                       .session()
+                       .tab()
+                       .navigation(1)
+                       .virtual_url());
+}
+
+// Ensure that the manager properly ignores a restored placeholder that refers
+// to a tab node that doesn't exist
+TEST_F(SessionsSyncManagerTest, RestoredPlacholderTabNodeDeleted) {
+  const int kNewWindowId = 1337;
+  syncer::SyncDataList in;
+  syncer::SyncChangeList out;
+
+  // Set up one tab and start sync with it.
+  AddTab(browser(), GURL(kFoo1));
+  NavigateAndCommitActiveTab(GURL(kFoo2));
+  InitWithSyncDataTakeOutput(in, &out);
+
+  // Should be one header add, 1 tab add, and one header update.
+  ASSERT_EQ(3U, out.size());
+  const sync_pb::EntitySpecifics t0_entity = out[1].sync_data().GetSpecifics();
+  ASSERT_TRUE(t0_entity.session().has_tab());
+
+  out.clear();
+  manager()->StopSyncing(syncer::SESSIONS);
+
+  // Override the tab with a placeholder tab delegate.
+  PlaceholderTabDelegate t0_override(t0_entity.session().tab().tab_id(),
+                                     t0_entity.session().tab_node_id());
+
+  // Set up the window override with the new window ID and placeholder tab.
+  const std::set<const SyncedWindowDelegate*>& windows =
+      get_synced_window_getter()->GetSyncedWindowDelegates();
+  ASSERT_EQ(1U, windows.size());
+  SyncedWindowDelegateOverride window_override(*windows.begin());
+  window_override.OverrideSessionId(kNewWindowId);
+  window_override.OverrideTabAt(0, &t0_override,
+                                t0_entity.session().tab().tab_id());
+
+  // Inject the window override.
+  std::set<const SyncedWindowDelegate*> delegates;
+  delegates.insert(&window_override);
+  std::unique_ptr<TestSyncedWindowDelegatesGetter> getter(
+      new TestSyncedWindowDelegatesGetter(delegates));
+  set_synced_window_getter(getter.get());
+
+  syncer::SyncMergeResult result = manager()->MergeDataAndStartSyncing(
+      syncer::SESSIONS, in, std::unique_ptr<syncer::SyncChangeProcessor>(
+                                new TestSyncProcessorStub(&out)),
+      std::unique_ptr<syncer::SyncErrorFactory>(
+          new syncer::SyncErrorFactoryMock()));
+
+  // Because no entities were passed in at associate time, there should be no
+  // tab changes.
+  ASSERT_EQ(0U, FilterOutLocalHeaderChanges(&out)->size());
 }
 
 // Tests MergeDataAndStartSyncing with sync data but no local data.
@@ -1140,7 +1299,8 @@
 
   syncer::SyncChangeList output;
   InitWithSyncDataTakeOutput(foreign_data, &output);
-  ASSERT_EQ(4U, output.size());
+  // Should be one header add, 1 tab add, and one header update.
+  ASSERT_EQ(3U, output.size());
 
   // Verify the local header.
   EXPECT_TRUE(output[0].IsValid());
@@ -1168,12 +1328,12 @@
   }
   EXPECT_EQ(SyncChange::ACTION_ADD, output[1].change_type());
   EXPECT_EQ(SyncChange::ACTION_UPDATE, output[2].change_type());
-  EXPECT_TRUE(output[2].sync_data().GetSpecifics().session().has_tab());
+  EXPECT_TRUE(output[1].sync_data().GetSpecifics().session().has_tab());
 
   // Verify the header was updated to reflect window state.
-  EXPECT_TRUE(output[3].IsValid());
-  EXPECT_EQ(SyncChange::ACTION_UPDATE, output[3].change_type());
-  const SyncData data_2(output[3].sync_data());
+  EXPECT_TRUE(output[2].IsValid());
+  EXPECT_EQ(SyncChange::ACTION_UPDATE, output[2].change_type());
+  const SyncData data_2(output[2].sync_data());
   EXPECT_EQ(manager()->current_machine_tag(),
             syncer::SyncDataLocal(data_2).GetTag());
   const sync_pb::SessionSpecifics& specifics2(data_2.GetSpecifics().session());
@@ -1216,7 +1376,9 @@
 
   syncer::SyncChangeList output1;
   InitWithSyncDataTakeOutput(foreign_data1, &output1);
-  ASSERT_EQ(4U, output1.size());
+
+  // 1 header add, one tab add, one header update.
+  ASSERT_EQ(3U, output1.size());
 
   // Add a second window to the foreign session.
   // TODO(tim): Bug 98892. Add local window too when observers are hooked up.
@@ -1307,10 +1469,10 @@
       tag, tab_nums1, &tabs));
 
   // Update associator with the session's meta node, window, and tabs.
-  manager()->UpdateTrackerWithForeignSession(meta, base::Time());
+  manager()->UpdateTrackerWithSpecifics(meta, base::Time());
   for (std::vector<sync_pb::SessionSpecifics>::iterator iter = tabs.begin();
        iter != tabs.end(); ++iter) {
-    manager()->UpdateTrackerWithForeignSession(*iter, base::Time());
+    manager()->UpdateTrackerWithSpecifics(*iter, base::Time());
   }
   ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
   ASSERT_EQ(1U, foreign_sessions.size());
@@ -1322,7 +1484,7 @@
   EXPECT_EQ(5U, changes.size());
   std::set<std::string> expected_tags(&tag, &tag + 1);
   for (int i = 0; i < 5; i++)
-    expected_tags.insert(TabNodePool::TabIdToTag(tag, i));
+    expected_tags.insert(TabNodeIdToTag(tag, i));
 
   for (int i = 0; i < 5; i++) {
     SCOPED_TRACE(changes[i].ToString());
@@ -1445,40 +1607,31 @@
   // committing the NavigationEntry. The first notification results in a tab
   // we don't associate although we do update the header node.  The second
   // notification triggers association of the tab, and the subsequent window
-  // update.  So we should see 4 changes at the SyncChangeProcessor.
-  ASSERT_EQ(4U, out.size());
+  // update.  So we should see 3 changes at the SyncChangeProcessor.
+  ASSERT_EQ(3U, out.size());
 
   EXPECT_EQ(SyncChange::ACTION_UPDATE, out[0].change_type());
   ASSERT_TRUE(out[0].sync_data().GetSpecifics().session().has_header());
   EXPECT_EQ(SyncChange::ACTION_ADD, out[1].change_type());
   int tab_node_id = out[1].sync_data().GetSpecifics().session().tab_node_id();
-  EXPECT_EQ(TabNodePool::TabIdToTag(
-                manager()->current_machine_tag(), tab_node_id),
+  EXPECT_EQ(TabNodeIdToTag(manager()->current_machine_tag(), tab_node_id),
             syncer::SyncDataLocal(out[1].sync_data()).GetTag());
   EXPECT_EQ(SyncChange::ACTION_UPDATE, out[2].change_type());
-  ASSERT_TRUE(out[2].sync_data().GetSpecifics().session().has_tab());
-  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[3].change_type());
-  ASSERT_TRUE(out[3].sync_data().GetSpecifics().session().has_header());
+  ASSERT_TRUE(out[2].sync_data().GetSpecifics().session().has_header());
 
   // Verify the actual content.
   const sync_pb::SessionHeader& session_header =
-      out[3].sync_data().GetSpecifics().session().header();
+      out[2].sync_data().GetSpecifics().session().header();
   ASSERT_EQ(1, session_header.window_size());
   EXPECT_EQ(1, session_header.window(0).tab_size());
   const sync_pb::SessionTab& tab1 =
-      out[2].sync_data().GetSpecifics().session().tab();
+      out[1].sync_data().GetSpecifics().session().tab();
   ASSERT_EQ(1, tab1.navigation_size());
   EXPECT_EQ(foo1.spec(), tab1.navigation(0).virtual_url());
 
   // Verify TabNodePool integrity.
-  EXPECT_EQ(1U, manager()->local_tab_pool_.Capacity());
-  EXPECT_TRUE(manager()->local_tab_pool_.Empty());
-
-  // Verify TabLinks.
-  SessionsSyncManager::TabLinksMap tab_map = manager()->local_tab_map_;
-  ASSERT_EQ(1U, tab_map.size());
-  int tab_id = out[2].sync_data().GetSpecifics().session().tab().tab_id();
-  EXPECT_EQ(tab_node_id, tab_map.find(tab_id)->second->tab_node_id());
+  EXPECT_EQ(1U, GetTabPool()->Capacity());
+  EXPECT_TRUE(GetTabPool()->Empty());
 }
 
 // Test that receiving a session delete from sync removes the session
@@ -1622,7 +1775,8 @@
       manager()->session_tracker_.LookupSessionTab(session_tag, 2, &tab));
 
   std::set<int> tab_node_ids;
-  manager()->session_tracker_.LookupTabNodeIds(session_tag, &tab_node_ids);
+  manager()->session_tracker_.LookupForeignTabNodeIds(session_tag,
+                                                      &tab_node_ids);
   EXPECT_EQ(6U, tab_node_ids.size());
   EXPECT_TRUE(tab_node_ids.find(tab1A.tab_node_id()) != tab_node_ids.end());
   EXPECT_TRUE(tab_node_ids.find(tab1B.tab_node_id()) != tab_node_ids.end());
@@ -1638,7 +1792,8 @@
   manager()->ProcessSyncChanges(FROM_HERE, changes);
 
   tab_node_ids.clear();
-  manager()->session_tracker_.LookupTabNodeIds(session_tag, &tab_node_ids);
+  manager()->session_tracker_.LookupForeignTabNodeIds(session_tag,
+                                                      &tab_node_ids);
   EXPECT_EQ(3U, tab_node_ids.size());
   EXPECT_TRUE(tab_node_ids.find(tab1C.tab_node_id()) != tab_node_ids.end());
   EXPECT_TRUE(tab_node_ids.find(tab2A.tab_node_id()) != tab_node_ids.end());
@@ -1676,7 +1831,8 @@
   output.clear();
 
   std::set<int> tab_node_ids;
-  manager()->session_tracker_.LookupTabNodeIds(session_tag, &tab_node_ids);
+  manager()->session_tracker_.LookupForeignTabNodeIds(session_tag,
+                                                      &tab_node_ids);
   EXPECT_EQ(2U, tab_node_ids.size());
   EXPECT_TRUE(tab_node_ids.find(tab_node_id_shared) != tab_node_ids.end());
   EXPECT_TRUE(tab_node_ids.find(tab_node_id_unique) != tab_node_ids.end());
@@ -1686,7 +1842,8 @@
   manager()->ProcessSyncChanges(FROM_HERE, changes);
 
   tab_node_ids.clear();
-  manager()->session_tracker_.LookupTabNodeIds(session_tag, &tab_node_ids);
+  manager()->session_tracker_.LookupForeignTabNodeIds(session_tag,
+                                                      &tab_node_ids);
   EXPECT_EQ(1U, tab_node_ids.size());
   EXPECT_TRUE(tab_node_ids.find(tab_node_id_unique) != tab_node_ids.end());
 
@@ -1694,34 +1851,45 @@
   EXPECT_EQ(1U, output.size());
 }
 
-// TODO(shashishekhar): "Move this to TabNodePool unittests."
-TEST_F(SessionsSyncManagerTest, SaveUnassociatedNodesForReassociation) {
+TEST_F(SessionsSyncManagerTest, AssociationReusesNodes) {
   syncer::SyncChangeList changes;
-  InitWithNoSyncData();
+  AddTab(browser(), GURL("http://foo1"));
+  InitWithSyncDataTakeOutput(syncer::SyncDataList(), &changes);
+  ASSERT_EQ(3U, changes.size());  // Header add, tab add, header update.
+  ASSERT_TRUE(changes[1].sync_data().GetSpecifics().session().has_tab());
+  int tab_node_id =
+      changes[1].sync_data().GetSpecifics().session().tab_node_id();
 
-  std::string local_tag = manager()->current_machine_tag();
-  // Create a free node and then dissassociate sessions so that it ends up
-  // unassociated.
-  manager()->local_tab_pool_.GetFreeTabNode(&changes);
-
-  // Update the tab_id of the node, so that it is considered a valid
-  // unassociated node otherwise it will be mistaken for a corrupted node and
-  // will be deleted before being added to the tab node pool.
-  sync_pb::EntitySpecifics entity(changes[0].sync_data().GetSpecifics());
-  entity.mutable_session()->mutable_tab()->set_tab_id(1);
-  SyncData d = CreateRemoteData(entity);
-  syncer::SyncDataList in(&d, &d + 1);
+  // Pass back the previous tab and header nodes at association, along with a
+  // second tab node (with a rewritten tab node id).
+  syncer::SyncDataList in;
+  in.push_back(
+      CreateRemoteData(changes[2].sync_data().GetSpecifics()));  // Header node.
+  sync_pb::SessionSpecifics new_tab(
+      changes[1].sync_data().GetSpecifics().session());
+  new_tab.set_tab_node_id(tab_node_id + 1);
+  in.push_back(CreateRemoteData(new_tab));  // New tab node.
+  in.push_back(CreateRemoteData(
+      changes[1].sync_data().GetSpecifics()));  // Old tab node.
   changes.clear();
-  SessionsSyncManager manager2(GetSyncSessionsClient(), sync_prefs(),
-                               local_device(), NewDummyRouter(),
-                               base::Closure(), base::Closure());
-  syncer::SyncMergeResult result = manager2.MergeDataAndStartSyncing(
+
+  // Reassociate (with the same single tab/window open).
+  manager()->StopSyncing(syncer::SESSIONS);
+  syncer::SyncMergeResult result = manager()->MergeDataAndStartSyncing(
       syncer::SESSIONS, in, std::unique_ptr<syncer::SyncChangeProcessor>(
                                 new TestSyncProcessorStub(&changes)),
       std::unique_ptr<syncer::SyncErrorFactory>(
           new syncer::SyncErrorFactoryMock()));
   ASSERT_FALSE(result.error().IsSet());
-  EXPECT_TRUE(FilterOutLocalHeaderChanges(&changes)->empty());
+
+  // No tab entities should be deleted. The original (lower) tab node id should
+  // be reused for association.
+  FilterOutLocalHeaderChanges(&changes);
+  ASSERT_EQ(1U, changes.size());
+  EXPECT_EQ(SyncChange::ACTION_UPDATE, changes[0].change_type());
+  EXPECT_TRUE(changes[0].sync_data().GetSpecifics().session().has_tab());
+  EXPECT_EQ(tab_node_id,
+            changes[0].sync_data().GetSpecifics().session().tab_node_id());
 }
 
 TEST_F(SessionsSyncManagerTest, MergeDeletesCorruptNode) {
@@ -1729,16 +1897,19 @@
   InitWithNoSyncData();
 
   std::string local_tag = manager()->current_machine_tag();
-  int tab_node_id = manager()->local_tab_pool_.GetFreeTabNode(&changes);
-  SyncData d = CreateRemoteData(changes[0].sync_data().GetSpecifics());
+  int tab_node_id = TabNodePool::kInvalidTabNodeID;
+  GetTabPool()->GetTabNodeForTab(0, &tab_node_id);
+  sync_pb::SessionSpecifics specifics;
+  specifics.set_session_tag(local_tag);
+  specifics.set_tab_node_id(tab_node_id);
+  SyncData d = CreateRemoteData(specifics);
   syncer::SyncDataList in(&d, &d + 1);
-  changes.clear();
   TearDown();
   SetUp();
   InitWithSyncDataTakeOutput(in, &changes);
   EXPECT_EQ(1U, FilterOutLocalHeaderChanges(&changes)->size());
   EXPECT_EQ(SyncChange::ACTION_DELETE, changes[0].change_type());
-  EXPECT_EQ(TabNodePool::TabIdToTag(local_tag, tab_node_id),
+  EXPECT_EQ(TabNodeIdToTag(local_tag, tab_node_id),
             syncer::SyncDataLocal(changes[0].sync_data()).GetTag());
 }
 
@@ -1807,7 +1978,7 @@
   // Go to a sync-interesting URL.
   NavigateAndCommitActiveTab(GURL("http://foo2"));
 
-  EXPECT_EQ(3U, out.size());  // Tab add, update, and header update.
+  EXPECT_EQ(2U, out.size());  // Tab add and header update.
 
   EXPECT_TRUE(
       base::StartsWith(syncer::SyncDataLocal(out[0].sync_data()).GetTag(),
@@ -1817,18 +1988,9 @@
             out[0].sync_data().GetSpecifics().session().session_tag());
   EXPECT_EQ(SyncChange::ACTION_ADD, out[0].change_type());
 
-  EXPECT_TRUE(
-      base::StartsWith(syncer::SyncDataLocal(out[1].sync_data()).GetTag(),
-                       manager()->current_machine_tag(),
-                       base::CompareCase::SENSITIVE));
-  EXPECT_EQ(manager()->current_machine_tag(),
-            out[1].sync_data().GetSpecifics().session().session_tag());
-  EXPECT_TRUE(out[1].sync_data().GetSpecifics().session().has_tab());
+  EXPECT_TRUE(out[1].IsValid());
   EXPECT_EQ(SyncChange::ACTION_UPDATE, out[1].change_type());
-
-  EXPECT_TRUE(out[2].IsValid());
-  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[2].change_type());
-  const SyncData data(out[2].sync_data());
+  const SyncData data(out[1].sync_data());
   EXPECT_EQ(manager()->current_machine_tag(),
             syncer::SyncDataLocal(data).GetTag());
   const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
@@ -1860,17 +2022,17 @@
   AddTab(browser(), bar1);
   NavigateAndCommitActiveTab(bar2);
 
-  // One add, one update for each AddTab.
-  // One update for each NavigateAndCommit.
-  // = 6 total tab updates.
-  // One header update corresponding to each of those.
-  // = 6 total header updates.
-  // 12 total updates.
-  ASSERT_EQ(12U, out.size());
+  // Change type breakdown:
+  const size_t kChangesPerTabCreation = 3;    // 1 tab add + 2 header updates.
+  const size_t kChangesPerTabNav = 2;         // 1 tab update + 1 header update.
+  const size_t kChangesPerTab = kChangesPerTabNav + kChangesPerTabCreation;
+  const size_t kNumTabs = 2;
+  const size_t kTotalUpdates = kChangesPerTab * kNumTabs;
+  ASSERT_EQ(kTotalUpdates, out.size());
 
   // Verify the tab node creations and updates to ensure the SyncProcessor
   // sees the right operations.
-  for (int i = 0; i < 12; i++) {
+  for (size_t i = 0; i < kTotalUpdates; i++) {
     SCOPED_TRACE(i);
     EXPECT_TRUE(out[i].IsValid());
     const SyncData data(out[i].sync_data());
@@ -1879,40 +2041,30 @@
                                  base::CompareCase::SENSITIVE));
     const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
     EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
-    if (i % 6 == 0) {
+    if (i % kChangesPerTab == 0) {
       // First thing on an AddTab is a no-op header update for parented tab.
       EXPECT_EQ(header.SerializeAsString(),
                 data.GetSpecifics().SerializeAsString());
       EXPECT_EQ(manager()->current_machine_tag(),
                 syncer::SyncDataLocal(data).GetTag());
-    } else if (i % 6 == 1) {
-      // Next, the TabNodePool should create the tab node.
+    } else if (i % kChangesPerTab == 1) {
+      // Next, the tab should be added.
       EXPECT_EQ(SyncChange::ACTION_ADD, out[i].change_type());
-      EXPECT_EQ(TabNodePool::TabIdToTag(
-                    manager()->current_machine_tag(),
-                    data.GetSpecifics().session().tab_node_id()),
+      EXPECT_EQ(TabNodeIdToTag(manager()->current_machine_tag(),
+                               data.GetSpecifics().session().tab_node_id()),
                 syncer::SyncDataLocal(data).GetTag());
-    } else if (i % 6 == 2) {
-      // Then we see the tab update to the URL.
-      EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
-      EXPECT_EQ(TabNodePool::TabIdToTag(
-                    manager()->current_machine_tag(),
-                    data.GetSpecifics().session().tab_node_id()),
-                syncer::SyncDataLocal(data).GetTag());
-      ASSERT_TRUE(specifics.has_tab());
-    } else if (i % 6 == 3) {
+    } else if (i % kChangesPerTab == 2) {
       // The header needs to be updated to reflect the new window state.
       EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
       EXPECT_TRUE(specifics.has_header());
-    } else if (i % 6 == 4) {
+    } else if (i % kChangesPerTab == 3) {
       // Now we move on to NavigateAndCommit.  Update the tab.
       EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
-      EXPECT_EQ(TabNodePool::TabIdToTag(
-                    manager()->current_machine_tag(),
-                    data.GetSpecifics().session().tab_node_id()),
+      EXPECT_EQ(TabNodeIdToTag(manager()->current_machine_tag(),
+                               data.GetSpecifics().session().tab_node_id()),
                 syncer::SyncDataLocal(data).GetTag());
       ASSERT_TRUE(specifics.has_tab());
-    } else if (i % 6 == 5) {
+    } else if (i % kChangesPerTab == 4) {
       // The header needs to be updated to reflect the new window state.
       EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
       ASSERT_TRUE(specifics.has_header());
@@ -1929,25 +2081,33 @@
   // ASSERT_TRUEs above allow us to dive in freely here.
   // Verify first tab.
   const sync_pb::SessionTab& tab1_1 =
-      out[2].sync_data().GetSpecifics().session().tab();
+      out[1].sync_data().GetSpecifics().session().tab();
   ASSERT_EQ(1, tab1_1.navigation_size());
   EXPECT_EQ(foo1.spec(), tab1_1.navigation(0).virtual_url());
   const sync_pb::SessionTab& tab1_2 =
-      out[4].sync_data().GetSpecifics().session().tab();
+      out[3].sync_data().GetSpecifics().session().tab();
   ASSERT_EQ(2, tab1_2.navigation_size());
   EXPECT_EQ(foo1.spec(), tab1_2.navigation(0).virtual_url());
   EXPECT_EQ(foo2.spec(), tab1_2.navigation(1).virtual_url());
 
   // Verify second tab.
   const sync_pb::SessionTab& tab2_1 =
-      out[8].sync_data().GetSpecifics().session().tab();
+      out[6].sync_data().GetSpecifics().session().tab();
   ASSERT_EQ(1, tab2_1.navigation_size());
   EXPECT_EQ(bar1.spec(), tab2_1.navigation(0).virtual_url());
   const sync_pb::SessionTab& tab2_2 =
-      out[10].sync_data().GetSpecifics().session().tab();
+      out[8].sync_data().GetSpecifics().session().tab();
   ASSERT_EQ(2, tab2_2.navigation_size());
   EXPECT_EQ(bar1.spec(), tab2_2.navigation(0).virtual_url());
   EXPECT_EQ(bar2.spec(), tab2_2.navigation(1).virtual_url());
+
+  // Verify tab delegates have Sync ids.
+  std::set<const SyncedWindowDelegate*> window_delegates =
+      get_synced_window_getter()->GetSyncedWindowDelegates();
+  // Sync ids are in reverse order because tabs are inserted at the beginning
+  // of the tab list.
+  EXPECT_EQ(1, (*window_delegates.begin())->GetTabAt(0)->GetSyncId());
+  EXPECT_EQ(0, (*window_delegates.begin())->GetTabAt(1)->GetSyncId());
 }
 
 // Check that if a tab becomes uninteresting (for example no syncable URLs),
@@ -1965,21 +2125,21 @@
 
   // Add an interesting tab.
   AddTab(browser(), kValidUrl);
-  // No-op header update, tab creation, tab update, header update.
-  ASSERT_EQ(4U, out.size());
+  // No-op header update, tab creation, header update.
+  ASSERT_EQ(3U, out.size());
   // The last two are the interesting updates.
-  ASSERT_TRUE(out[2].sync_data().GetSpecifics().session().has_tab());
-  EXPECT_EQ(kValidUrl.spec(), out[2]
+  ASSERT_TRUE(out[1].sync_data().GetSpecifics().session().has_tab());
+  EXPECT_EQ(kValidUrl.spec(), out[1]
                                   .sync_data()
                                   .GetSpecifics()
                                   .session()
                                   .tab()
                                   .navigation(0)
                                   .virtual_url());
-  ASSERT_TRUE(out[3].sync_data().GetSpecifics().session().has_header());
+  ASSERT_TRUE(out[2].sync_data().GetSpecifics().session().has_header());
   ASSERT_EQ(1,
-            out[3].sync_data().GetSpecifics().session().header().window_size());
-  ASSERT_EQ(1, out[3]
+            out[2].sync_data().GetSpecifics().session().header().window_size());
+  ASSERT_EQ(1, out[2]
                    .sync_data()
                    .GetSpecifics()
                    .session()
@@ -2015,7 +2175,7 @@
 
   syncer::SyncChangeList out;
   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
-  ASSERT_EQ(6U, out.size());
+  ASSERT_EQ(4U, out.size());  // Header creation, add two tabs, header update
 
   // Check that this machine's data is not included in the foreign windows.
   std::vector<const SyncedSession*> foreign_sessions;
@@ -2036,7 +2196,7 @@
   EXPECT_EQ(0, header_s.window_size());
 
   // Verify the tab node creations and updates with content.
-  for (int i = 1; i < 5; i++) {
+  for (int i = 1; i < 3; i++) {
     EXPECT_TRUE(out[i].IsValid());
     const SyncData data(out[i].sync_data());
     EXPECT_TRUE(base::StartsWith(syncer::SyncDataLocal(data).GetTag(),
@@ -2044,18 +2204,13 @@
                                  base::CompareCase::SENSITIVE));
     const sync_pb::SessionSpecifics& specifics(data.GetSpecifics().session());
     EXPECT_EQ(manager()->current_machine_tag(), specifics.session_tag());
-    if (i % 2 == 1) {
-      EXPECT_EQ(SyncChange::ACTION_ADD, out[i].change_type());
-    } else {
-      EXPECT_EQ(SyncChange::ACTION_UPDATE, out[i].change_type());
-      EXPECT_TRUE(specifics.has_tab());
-    }
+    EXPECT_EQ(SyncChange::ACTION_ADD, out[i].change_type());
   }
 
   // Verify the header was updated to reflect new window state.
-  EXPECT_TRUE(out[5].IsValid());
-  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[5].change_type());
-  const SyncData data_2(out[5].sync_data());
+  EXPECT_TRUE(out[3].IsValid());
+  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[3].change_type());
+  const SyncData data_2(out[3].sync_data());
   EXPECT_EQ(manager()->current_machine_tag(),
             syncer::SyncDataLocal(data_2).GetTag());
   const sync_pb::SessionSpecifics& specifics2(data_2.GetSpecifics().session());
@@ -2064,19 +2219,13 @@
   const sync_pb::SessionHeader& header_s2 = specifics2.header();
   EXPECT_EQ(1, header_s2.window_size());
 
-  // Verify TabLinks.
-  SessionsSyncManager::TabLinksMap tab_map = manager()->local_tab_map_;
-  ASSERT_EQ(2U, tab_map.size());
-  // Tabs are ordered by sessionid in tab_map, so should be able to traverse
-  // the tree based on order of tabs created
-  SessionsSyncManager::TabLinksMap::iterator iter = tab_map.begin();
-  ASSERT_EQ(2, iter->second->tab()->GetEntryCount());
-  EXPECT_EQ(GURL("http://foo1"), iter->second->tab()->GetVirtualURLAtIndex(0));
-  EXPECT_EQ(GURL("http://foo2"), iter->second->tab()->GetVirtualURLAtIndex(1));
-  iter++;
-  ASSERT_EQ(2, iter->second->tab()->GetEntryCount());
-  EXPECT_EQ(GURL("http://bar1"), iter->second->tab()->GetVirtualURLAtIndex(0));
-  EXPECT_EQ(GURL("http://bar2"), iter->second->tab()->GetVirtualURLAtIndex(1));
+  // Verify tab delegates have Sync ids.
+  std::set<const SyncedWindowDelegate*> window_delegates =
+      get_synced_window_getter()->GetSyncedWindowDelegates();
+  // Sync ids are in same order as tabs because the association happens after
+  // the tabs are opened (and therefore iterates through same order).
+  EXPECT_EQ(0, (*window_delegates.begin())->GetTabAt(0)->GetSyncId());
+  EXPECT_EQ(1, (*window_delegates.begin())->GetTabAt(1)->GetSyncId());
 }
 
 TEST_F(SessionsSyncManagerTest, ForeignSessionModifiedTime) {
@@ -2179,8 +2328,7 @@
   for (int i = 1; i < 5; i++) {
     EXPECT_EQ(SyncChange::ACTION_DELETE, output[i].change_type());
     const SyncData data(output[i].sync_data());
-    EXPECT_EQ(TabNodePool::TabIdToTag(tag1, i),
-              syncer::SyncDataLocal(data).GetTag());
+    EXPECT_EQ(TabNodeIdToTag(tag1, i), syncer::SyncDataLocal(data).GetTag());
   }
 
   ASSERT_TRUE(manager()->GetAllForeignSessions(&foreign_sessions));
@@ -2303,7 +2451,8 @@
 
   syncer::SyncChangeList out;
   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
-  ASSERT_EQ(4U, out.size());  // Header, tab ADD, tab UPDATE, header UPDATE.
+  ASSERT_EQ(3U, out.size());  // Header ADD, tab ADD, header UPDATE.
+  out.clear();
 
   // To simulate WebContents swap during prerendering, create new WebContents
   // and swap with old WebContents.
@@ -2324,24 +2473,28 @@
       old_web_contents.get());
   browser()->tab_strip_model()->ReplaceWebContentsAt(index, new_web_contents);
 
-  ASSERT_EQ(9U, out.size());
-  EXPECT_EQ(SyncChange::ACTION_ADD, out[4].change_type());
-  EXPECT_EQ(SyncChange::ACTION_UPDATE, out[5].change_type());
+  ASSERT_EQ(4U, out.size());
+  EXPECT_EQ(SyncChange::ACTION_ADD, out[0].change_type());
+  out.clear();
 
-  // Navigate away.
+  // Navigate away. +1 tab updates, 1 header update.
   NavigateAndCommitActiveTab(GURL("http://bar2"));
 
   // Delete old WebContents. This should not crash.
+  // +1 no-op header update.
   old_web_contents.reset();
 
   // Try more navigations and verify output size. This can also reveal
   // bugs (leaks) on memcheck bots if the SessionSyncManager
   // didn't properly clean up the tab pool or session tracker.
+  // +1 tab updates, 1 header update.
   NavigateAndCommitActiveTab(GURL("http://bar3"));
 
+  // +1 no-op header update, tab add, header update.
   AddTab(browser(), GURL("http://bar4"));
+  // +1 tab update, header update.
   NavigateAndCommitActiveTab(GURL("http://bar5"));
-  ASSERT_EQ(19U, out.size());
+  ASSERT_EQ(10U, out.size());
 }
 
 // Test that NOTIFICATION_FOREIGN_SESSION_UPDATED is sent when processing
diff --git a/chrome/browser/translate/language_model_factory_unittest.cc b/chrome/browser/translate/language_model_factory_unittest.cc
new file mode 100644
index 0000000..46f1ca9
--- /dev/null
+++ b/chrome/browser/translate/language_model_factory_unittest.cc
@@ -0,0 +1,24 @@
+// Copyright 2017 The Chromium 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/translate/language_model_factory.h"
+
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using testing::IsNull;
+using testing::Not;
+
+TEST(LanguageModelFactoryTest, NotCreatedInIncognito) {
+  content::TestBrowserThreadBundle thread_bundle;
+  TestingProfile profile;
+
+  EXPECT_THAT(LanguageModelFactory::GetForBrowserContext(&profile),
+              Not(IsNull()));
+
+  Profile* incognito = profile.GetOffTheRecordProfile();
+  ASSERT_THAT(incognito, Not(IsNull()));
+  EXPECT_THAT(LanguageModelFactory::GetForBrowserContext(incognito), IsNull());
+}
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc
index 1a4ca85b..04f6e8e 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc
@@ -14,7 +14,6 @@
 #include <utility>
 #include <vector>
 
-#include "ash/common/ash_switches.h"
 #include "ash/common/shelf/shelf_constants.h"
 #include "ash/common/shelf/shelf_controller.h"
 #include "ash/common/shelf/shelf_item_types.h"
@@ -299,7 +298,6 @@
   void SetUp() override {
     base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
     command_line->AppendSwitch(switches::kUseFirstDisplayAsInternal);
-    command_line->AppendSwitch(ash::switches::kAshEnableTouchViewTesting);
 
     app_list::AppListSyncableServiceFactory::SetUseInTesting();
 
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
index 3b5cf75..0446be9 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -586,9 +586,13 @@
 
 void OmniboxResultView::InitContentsRenderTextIfNecessary() const {
   if (!contents_rendertext_) {
-    contents_rendertext_.reset(
-        CreateClassifiedRenderText(
-            match_.contents, match_.contents_class, false).release());
+    if (match_.answer) {
+      contents_rendertext_ =
+          CreateAnswerLine(match_.answer->first_line(), font_list_);
+    } else {
+      contents_rendertext_ = CreateClassifiedRenderText(
+          match_.contents, match_.contents_class, false);
+    }
   }
 }
 
@@ -643,8 +647,6 @@
 
     if (!description_rendertext_) {
       if (match_.answer) {
-        contents_rendertext_ =
-            CreateAnswerLine(match_.answer->first_line(), font_list_);
         description_rendertext_ =
             CreateAnswerLine(match_.answer->second_line(), font_list_);
       } else if (!match_.description.empty()) {
@@ -661,17 +663,13 @@
     int x = GetMirroredXForRect(keyword_text_bounds_);
     mirroring_context_->Initialize(x, keyword_text_bounds_.width());
     if (!keyword_contents_rendertext_) {
-      keyword_contents_rendertext_.reset(
-          CreateClassifiedRenderText(keyword_match->contents,
-                                     keyword_match->contents_class,
-                                     false).release());
+      keyword_contents_rendertext_ = CreateClassifiedRenderText(
+          keyword_match->contents, keyword_match->contents_class, false);
     }
     if (!keyword_description_rendertext_ &&
         !keyword_match->description.empty()) {
-      keyword_description_rendertext_.reset(
-          CreateClassifiedRenderText(keyword_match->description,
-                                     keyword_match->description_class,
-                                     true).release());
+      keyword_description_rendertext_ = CreateClassifiedRenderText(
+          keyword_match->description, keyword_match->description_class, true);
     }
     PaintMatch(*keyword_match, keyword_contents_rendertext_.get(),
                keyword_description_rendertext_.get(), canvas, x);
diff --git a/chrome/browser/ui/webui/welcome_win10_ui.cc b/chrome/browser/ui/webui/welcome_win10_ui.cc
index cf416e30..d5cc294b 100644
--- a/chrome/browser/ui/webui/welcome_win10_ui.cc
+++ b/chrome/browser/ui/webui/welcome_win10_ui.cc
@@ -91,6 +91,8 @@
     : content::WebUIController(web_ui) {
   static const char kCssFilePath[] = "welcome.css";
   static const char kJsFilePath[] = "welcome.js";
+  static const char kDefaultFilePath[] = "default.webp";
+  static const char kPinFilePath[] = "pin.webp";
 
   Profile* profile = Profile::FromWebUI(web_ui);
 
@@ -112,10 +114,18 @@
   if (is_inline_style) {
     html_source->AddResourcePath(kCssFilePath, IDR_WELCOME_WIN10_INLINE_CSS);
     html_source->AddResourcePath(kJsFilePath, IDR_WELCOME_WIN10_INLINE_JS);
+    html_source->AddResourcePath(kDefaultFilePath,
+                                 IDR_WELCOME_WIN10_DEFAULT_SMALL_WEBP);
+    html_source->AddResourcePath(kPinFilePath,
+                                 IDR_WELCOME_WIN10_PIN_SMALL_WEBP);
     html_source->SetDefaultResource(IDR_WELCOME_WIN10_INLINE_HTML);
   } else {
     html_source->AddResourcePath(kCssFilePath, IDR_WELCOME_WIN10_SECTIONED_CSS);
     html_source->AddResourcePath(kJsFilePath, IDR_WELCOME_WIN10_SECTIONED_JS);
+    html_source->AddResourcePath(kDefaultFilePath,
+                                 IDR_WELCOME_WIN10_DEFAULT_LARGE_WEBP);
+    html_source->AddResourcePath(kPinFilePath,
+                                 IDR_WELCOME_WIN10_PIN_LARGE_WEBP);
     html_source->SetDefaultResource(IDR_WELCOME_WIN10_SECTIONED_HTML);
   }
 
diff --git a/chrome/installer/util/lzma_file_allocator_unittest.cc b/chrome/installer/util/lzma_file_allocator_unittest.cc
index 5cf37b99..6a5ceda 100644
--- a/chrome/installer/util/lzma_file_allocator_unittest.cc
+++ b/chrome/installer/util/lzma_file_allocator_unittest.cc
@@ -32,7 +32,7 @@
 }
 
 TEST_F(LzmaFileAllocatorTest, ReadAndWriteWithMultipleSizeTest) {
-  const char kSampleExpectedCharacter = 'a';
+  static const char kSampleExpectedCharacter = 'a';
   SYSTEM_INFO sysinfo;
   ::GetSystemInfo(&sysinfo);
   EXPECT_GT(sysinfo.dwPageSize, 0U);
@@ -44,7 +44,7 @@
     LzmaFileAllocator allocator(temp_dir_.GetPath());
     char* s = reinterpret_cast<char*>(IAlloc_Alloc(&allocator, size));
     std::fill_n(s, size, kSampleExpectedCharacter);
-    char* ret = std::find_if(s, s + size, [&kSampleExpectedCharacter](char c) {
+    char* ret = std::find_if(s, s + size, [](char c) {
       return c != kSampleExpectedCharacter;
     });
     EXPECT_EQ(s + size, ret);
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 7179c43..c6378c0 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2186,7 +2186,6 @@
         "../browser/chromeos/app_mode/arc/arc_kiosk_app_manager_browsertest.cc",
         "../browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc",
         "../browser/chromeos/app_mode/kiosk_app_update_service_browsertest.cc",
-        "../browser/chromeos/app_mode/kiosk_crash_restore_browsertest.cc",
         "../browser/chromeos/arc/arc_session_manager_browsertest.cc",
         "../browser/chromeos/arc/auth/arc_robot_auth_code_fetcher_browsertest.cc",
         "../browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc",
@@ -2231,6 +2230,7 @@
         "../browser/chromeos/first_run/goodies_displayer_browsertest.cc",
         "../browser/chromeos/input_method/input_method_engine_browsertests.cc",
         "../browser/chromeos/input_method/mode_indicator_browsertest.cc",
+        "../browser/chromeos/login/auto_launched_kiosk_browsertest.cc",
         "../browser/chromeos/login/bluetooth_host_pairing_browsertest.cc",
         "../browser/chromeos/login/crash_restore_browsertest.cc",
         "../browser/chromeos/login/demo_mode/demo_app_launcher_browsertest.cc",
@@ -3333,6 +3333,7 @@
     "../browser/thumbnails/content_based_thumbnailing_algorithm_unittest.cc",
     "../browser/thumbnails/simple_thumbnail_crop_unittest.cc",
     "../browser/thumbnails/thumbnail_service_unittest.cc",
+    "../browser/translate/language_model_factory_unittest.cc",
     "../browser/translate/translate_service_unittest.cc",
     "../browser/ui/android/tab_model/tab_model_list_unittest.cc",
     "../browser/ui/android/tab_model/tab_model_unittest.cc",
diff --git a/chrome/test/data/page_with_embedded_pdf.html b/chrome/test/data/page_with_embedded_pdf.html
index ca83dbb..9b0028da 100644
--- a/chrome/test/data/page_with_embedded_pdf.html
+++ b/chrome/test/data/page_with_embedded_pdf.html
@@ -3,5 +3,5 @@
 </head>
 <body>
     <p> This page embeds a PDF. </p>
-    <embed src="./pdf/test.pdf" />
+    <embed src="./pdf/test.pdf" type="application/pdf"/>
 </body>
diff --git a/chrome/test/data/payments/alicepay_bobpay_charliepay_and_cards.js b/chrome/test/data/payments/alicepay_bobpay_charliepay_and_cards.js
new file mode 100644
index 0000000..db3f719b
--- /dev/null
+++ b/chrome/test/data/payments/alicepay_bobpay_charliepay_and_cards.js
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* global PaymentRequest:false */
+
+/**
+ * Launches the PaymentRequest UI with Bob Pay, Alice Pay and credit cards as
+ * payment methods.
+ */
+function buy() {  // eslint-disable-line no-unused-vars
+  try {
+    new PaymentRequest(
+        [{supportedMethods: ['https://alicepay.com', 'https://bobpay.com',
+            'https://charliepay.com', 'visa', 'mastercard']}],
+        {total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}}})
+        .show()
+        .then(function(resp) {
+          resp.complete('success')
+              .then(function() {
+                print(resp.methodName + '<br>' +
+                      JSON.stringify(resp.details, undefined, 2));
+              })
+              .catch(function(error) {
+                print(error.message);
+              });
+        })
+        .catch(function(error) {
+          print(error.message);
+        });
+  } catch (error) {
+    print(error.message);
+  }
+}
diff --git a/chrome/test/data/payments/payment_request_alicepay_bobpay_charliepay_and_cards_test.html b/chrome/test/data/payments/payment_request_alicepay_bobpay_charliepay_and_cards_test.html
new file mode 100644
index 0000000..34effdc
--- /dev/null
+++ b/chrome/test/data/payments/payment_request_alicepay_bobpay_charliepay_and_cards_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!--
+Copyright 2017 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+<html>
+<head>
+<title>Alice Pay, Bob Pay, Charlie Pay and Cards Test</title>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+<link rel="stylesheet" type="text/css" href="style.css">
+</head>
+<body>
+<button onclick="buy()" id="buy">Multiple apps and Cards Test</button><br>
+<pre id="result"></pre>
+<script src="util.js"></script>
+<script src="alicepay_bobpay_charliepay_and_cards.js"></script>
+</body>
+</html>
diff --git a/chrome/test/data/webui/settings/startup_urls_page_test.js b/chrome/test/data/webui/settings/startup_urls_page_test.js
index 8028da3..b502e999 100644
--- a/chrome/test/data/webui/settings/startup_urls_page_test.js
+++ b/chrome/test/data/webui/settings/startup_urls_page_test.js
@@ -183,6 +183,22 @@
       document.body.appendChild(dialog);
       return testProxyCalled('editStartupPage');
     });
+
+    test('Enter key submits', function() {
+      document.body.appendChild(dialog);
+
+      // Input a URL and force validation.
+      var inputElement = dialog.$.url;
+      inputElement.value = 'foo.com';
+      pressSpace(inputElement);
+
+      return browserProxy.whenCalled('validateStartupPage').then(function() {
+        MockInteractions.keyEventOn(
+            inputElement, 'keypress', 13, undefined, 'Enter');
+
+        return browserProxy.whenCalled('addStartupPage');
+      });
+    });
   });
 
   suite('StartupUrlsPage', function() {
diff --git a/chrome/test/remoting/webapp_javascript_browsertest.cc b/chrome/test/remoting/webapp_javascript_browsertest.cc
index f8b2e68f7..b70e354 100644
--- a/chrome/test/remoting/webapp_javascript_browsertest.cc
+++ b/chrome/test/remoting/webapp_javascript_browsertest.cc
@@ -14,7 +14,8 @@
 
 // Disable test on (dbg) as it takes longer than 30s to complete.
 // https://crbug.com/504204.
-#if (!defined(NDEBUG))
+// Also disable on ASAN due to flake: crbug.com/685025
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
 #define MAYBE_Remoting_Webapp_Js_Unittest DISABLED_Remoting_Webapp_Js_Unittest
 #else
 #define MAYBE_Remoting_Webapp_Js_Unittest Remoting_Webapp_Js_Unittest
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc
index 9e04b6d..48caceec 100644
--- a/chromeos/chromeos_switches.cc
+++ b/chromeos/chromeos_switches.cc
@@ -55,6 +55,11 @@
 // mode. This can be enabled by this flag.
 const char kAllowRAInDevMode[] = "allow-ra-in-dev-mode";
 
+// Specifies whether an app launched in kiosk mode was auto launched with zero
+// delay. Used in order to properly restore auto-launched state during session
+// restore flow.
+const char kAppAutoLaunched[] = "app-auto-launched";
+
 // Path for app's OEM manifest file.
 const char kAppOemManifestFile[] = "app-mode-oem-manifest";
 
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h
index 90e0850..86d216a 100644
--- a/chromeos/chromeos_switches.h
+++ b/chromeos/chromeos_switches.h
@@ -27,6 +27,7 @@
 CHROMEOS_EXPORT extern const char kAllowDataRoamingByDefault[];
 CHROMEOS_EXPORT extern const char kAllowFailedPolicyFetchForTest[];
 CHROMEOS_EXPORT extern const char kAllowRAInDevMode[];
+CHROMEOS_EXPORT extern const char kAppAutoLaunched[];
 CHROMEOS_EXPORT extern const char kAppOemManifestFile[];
 CHROMEOS_EXPORT extern const char kArcAvailable[];
 CHROMEOS_EXPORT extern const char kArtifactsDir[];
diff --git a/components/autofill/core/browser/autofill_data_model.cc b/components/autofill/core/browser/autofill_data_model.cc
index 4f42566..5457f3d 100644
--- a/components/autofill/core/browser/autofill_data_model.cc
+++ b/components/autofill/core/browser/autofill_data_model.cc
@@ -50,6 +50,8 @@
   // of the profile and leveraging the properties of the logarithmic function.
   // DaysSinceLastUse() and |use_count_| are offset because their minimum values
   // are respectively 0 and 1 but the formula requires at least a value of 2.
+  // Please update getFrecencyScore in PaymentRequestImpl.java as well if below
+  // formula needs update.
   return -log((time - use_date_).InDays() + 2) / log(use_count_ + 1);
 }
 
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc
index 6c7488b..1acbeeed 100644
--- a/components/browser_sync/profile_sync_service.cc
+++ b/components/browser_sync/profile_sync_service.cc
@@ -212,7 +212,6 @@
       gaia_cookie_manager_service_(init_params.gaia_cookie_manager_service),
       network_resources_(new syncer::HttpBridgeNetworkResources),
       start_behavior_(init_params.start_behavior),
-      catch_up_configure_in_progress_(false),
       passphrase_prompt_triggered_by_version_(false),
       sync_enabled_weak_factory_(this),
       weak_factory_(this) {
@@ -784,7 +783,6 @@
   encrypt_everything_ = false;
   encrypted_types_ = syncer::SyncEncryptionHandler::SensitiveTypes();
   passphrase_required_reason_ = syncer::REASON_PASSPHRASE_NOT_REQUIRED;
-  catch_up_configure_in_progress_ = false;
   access_token_.clear();
   request_access_token_retry_timer_.Stop();
   last_snapshot_ = syncer::SyncCycleSnapshot();
@@ -1311,7 +1309,6 @@
   sync_prefs_.GetNigoriSpecificsForPassphraseTransition(
       &saved_nigori_state_->nigori_specifics);
   const syncer::ModelTypeSet types = GetActiveDataTypes();
-  catch_up_configure_in_progress_ = true;
   data_type_manager_->Configure(types, syncer::CONFIGURE_REASON_CATCH_UP);
 }
 
@@ -1383,7 +1380,7 @@
 
   // Handle unrecoverable error.
   if (configure_status_ != DataTypeManager::OK) {
-    if (catch_up_configure_in_progress_) {
+    if (result.was_catch_up_configure) {
       // Record catchup configuration failure.
       UMA_HISTOGRAM_ENUMERATION(kClearServerDataEventsHistogramName,
                                 CLEAR_SERVER_DATA_CATCHUP_FAILED,
@@ -1427,8 +1424,7 @@
     return;
   }
 
-  if (catch_up_configure_in_progress_) {
-    catch_up_configure_in_progress_ = false;
+  if (result.was_catch_up_configure) {
     ClearAndRestartSyncForPassphraseEncryption();
     return;
   }
@@ -1731,12 +1727,9 @@
 
 syncer::ModelTypeSet ProfileSyncService::GetActiveDataTypes() const {
   DCHECK(thread_checker_.CalledOnValidThread());
-  if (!IsSyncActive() || !ConfigurationDone())
+  if (!data_type_manager_)
     return syncer::ModelTypeSet();
-  const syncer::ModelTypeSet preferred_types = GetPreferredDataTypes();
-  const syncer::ModelTypeSet failed_types =
-      data_type_status_table_.GetFailedTypes();
-  return Difference(preferred_types, failed_types);
+  return data_type_manager_->GetActiveDataTypes();
 }
 
 syncer::SyncClient* ProfileSyncService::GetSyncClient() const {
diff --git a/components/browser_sync/profile_sync_service.h b/components/browser_sync/profile_sync_service.h
index 9d7c709..31f973f 100644
--- a/components/browser_sync/profile_sync_service.h
+++ b/components/browser_sync/profile_sync_service.h
@@ -943,12 +943,6 @@
   std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState>
       saved_nigori_state_;
 
-  // When BeginConfigureCatchUpBeforeClear is called it will set
-  // catch_up_configure_in_progress_ to true. This is needed to detect that call
-  // to OnConfigureDone originated from BeginConfigureCatchUpBeforeClear and
-  // needs to be followed by ClearAndRestartSyncForPassphraseEncryption().
-  bool catch_up_configure_in_progress_;
-
   // Whether the major version has changed since the last time Chrome ran,
   // and therefore a passphrase required state should result in prompting
   // the user. This logic is only enabled on platforms that consume the
diff --git a/components/browser_sync/profile_sync_service_unittest.cc b/components/browser_sync/profile_sync_service_unittest.cc
index 916d3b3e..24d5b41 100644
--- a/components/browser_sync/profile_sync_service_unittest.cc
+++ b/components/browser_sync/profile_sync_service_unittest.cc
@@ -41,6 +41,7 @@
 
 using syncer::DataTypeController;
 using syncer::FakeSyncEngine;
+using syncer::ModelTypeSet;
 using syncer::SyncMergeResult;
 using testing::Return;
 
@@ -71,7 +72,8 @@
   void PurgeForMigration(syncer::ModelTypeSet undesired_types,
                          syncer::ConfigureReason reason) override {}
   void Stop() override{};
-  State state() const override { return syncer::DataTypeManager::CONFIGURED; };
+  ModelTypeSet GetActiveDataTypes() const override { return ModelTypeSet(); }
+  State state() const override { return syncer::DataTypeManager::CONFIGURED; }
 
  private:
   ConfigureCalled configure_called_;
@@ -259,6 +261,8 @@
   void OnConfigureCalled(syncer::ConfigureReason configure_reason) {
     syncer::DataTypeManager::ConfigureResult result;
     result.status = syncer::DataTypeManager::OK;
+    if (configure_reason == syncer::CONFIGURE_REASON_CATCH_UP)
+      result.was_catch_up_configure = true;
     service()->OnConfigureDone(result);
   }
 
@@ -734,7 +738,9 @@
   EXPECT_TRUE(captured_callback.is_null());
 
   // Simulate configure successful. Ensure that SBH::ClearServerData is called.
+  result.was_catch_up_configure = true;
   service()->OnConfigureDone(result);
+  result.was_catch_up_configure = false;
   EXPECT_FALSE(captured_callback.is_null());
 
   // Once SBH::ClearServerData finishes successfully ensure that sync is
@@ -793,7 +799,9 @@
 
   // Simulate catch up configure successful. Ensure that SBH::ClearServerData is
   // called.
+  result.was_catch_up_configure = true;
   service()->OnConfigureDone(result);
+  result.was_catch_up_configure = false;
   EXPECT_FALSE(captured_callback.is_null());
 
   ExpectSyncEngineCreation(1);
@@ -845,7 +853,9 @@
 
   // Simulate catch up configure successful. Ensure that SBH::ClearServerData is
   // called.
+  result.was_catch_up_configure = true;
   service()->OnConfigureDone(result);
+  result.was_catch_up_configure = false;
   EXPECT_FALSE(captured_callback.is_null());
 
   ExpectSyncEngineCreation(1);
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc
index ab7a96b..3db8748 100644
--- a/components/exo/shell_surface.cc
+++ b/components/exo/shell_surface.cc
@@ -1498,6 +1498,7 @@
       shadow_overlay_->Init(ui::LAYER_NOT_DRAWN);
       shadow_overlay_->layer()->Add(shadow->layer());
       window->AddChild(shadow_overlay_);
+      window->StackChildAbove(shadow_overlay_, shadow_underlay_);
       shadow_overlay_->Show();
     }
     shadow_overlay_->SetBounds(shadow_bounds);
diff --git a/components/exo/shell_surface.h b/components/exo/shell_surface.h
index d644559..6a85feb 100644
--- a/components/exo/shell_surface.h
+++ b/components/exo/shell_surface.h
@@ -238,6 +238,7 @@
   // Overridden from ui::AcceleratorTarget:
   bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
 
+  aura::Window* shadow_overlay() { return shadow_overlay_; }
   aura::Window* shadow_underlay() { return shadow_underlay_; }
 
  private:
diff --git a/components/exo/shell_surface_unittest.cc b/components/exo/shell_surface_unittest.cc
index 135395c..3df1796 100644
--- a/components/exo/shell_surface_unittest.cc
+++ b/components/exo/shell_surface_unittest.cc
@@ -559,6 +559,14 @@
 
   EXPECT_EQ(wm::ShadowElevation::MEDIUM, wm::GetShadowElevation(window));
   EXPECT_TRUE(shadow->layer()->visible());
+
+  // Shadow overlay should be stacked just above the shadow underlay.
+  auto underlay_it =
+      std::find(window->children().begin(), window->children().end(),
+                shell_surface->shadow_underlay());
+  ASSERT_NE(underlay_it, window->children().end());
+  ASSERT_NE(std::next(underlay_it), window->children().end());
+  EXPECT_EQ(*std::next(underlay_it), shell_surface->shadow_overlay());
 }
 
 TEST_F(ShellSurfaceTest, ShadowWithStateChange) {
diff --git a/components/safe_browsing_db/BUILD.gn b/components/safe_browsing_db/BUILD.gn
index cf8f51c..5d08673 100644
--- a/components/safe_browsing_db/BUILD.gn
+++ b/components/safe_browsing_db/BUILD.gn
@@ -322,6 +322,7 @@
     "v4_update_protocol_manager.h",
   ]
   deps = [
+    ":safe_browsing_prefs",
     ":safebrowsing_proto",
     ":util",
     ":v4_protocol_manager_util",
diff --git a/components/safe_browsing_db/v4_local_database_manager.cc b/components/safe_browsing_db/v4_local_database_manager.cc
index 58f7ae8..224525982 100644
--- a/components/safe_browsing_db/v4_local_database_manager.cc
+++ b/components/safe_browsing_db/v4_local_database_manager.cc
@@ -128,16 +128,21 @@
 
 // static
 scoped_refptr<V4LocalDatabaseManager> V4LocalDatabaseManager::Create(
-    const base::FilePath& base_path) {
+    const base::FilePath& base_path,
+    ExtendedReportingLevelCallback extended_reporting_level_callback) {
   if (!V4FeatureList::IsLocalDatabaseManagerEnabled()) {
     return nullptr;
   }
 
-  return make_scoped_refptr(new V4LocalDatabaseManager(base_path));
+  return make_scoped_refptr(
+      new V4LocalDatabaseManager(base_path, extended_reporting_level_callback));
 }
 
-V4LocalDatabaseManager::V4LocalDatabaseManager(const base::FilePath& base_path)
+V4LocalDatabaseManager::V4LocalDatabaseManager(
+    const base::FilePath& base_path,
+    ExtendedReportingLevelCallback extended_reporting_level_callback)
     : base_path_(base_path),
+      extended_reporting_level_callback_(extended_reporting_level_callback),
       list_infos_(GetListInfos()),
       weak_factory_(this) {
   DCHECK(!base_path_.empty());
@@ -707,12 +712,13 @@
 void V4LocalDatabaseManager::SetupUpdateProtocolManager(
     net::URLRequestContextGetter* request_context_getter,
     const V4ProtocolConfig& config) {
-  V4UpdateCallback callback =
+  V4UpdateCallback update_callback =
       base::Bind(&V4LocalDatabaseManager::UpdateRequestCompleted,
                  weak_factory_.GetWeakPtr());
 
-  v4_update_protocol_manager_ =
-      V4UpdateProtocolManager::Create(request_context_getter, config, callback);
+  v4_update_protocol_manager_ = V4UpdateProtocolManager::Create(
+      request_context_getter, config, update_callback,
+      extended_reporting_level_callback_);
 }
 
 void V4LocalDatabaseManager::UpdateRequestCompleted(
diff --git a/components/safe_browsing_db/v4_local_database_manager.h b/components/safe_browsing_db/v4_local_database_manager.h
index 12d63a8..f24e3e9 100644
--- a/components/safe_browsing_db/v4_local_database_manager.h
+++ b/components/safe_browsing_db/v4_local_database_manager.h
@@ -31,7 +31,8 @@
   // Create and return an instance of V4LocalDatabaseManager, if Finch trial
   // allows it; nullptr otherwise.
   static scoped_refptr<V4LocalDatabaseManager> Create(
-      const base::FilePath& base_path);
+      const base::FilePath& base_path,
+      ExtendedReportingLevelCallback extended_reporting_level_callback);
 
   //
   // SafeBrowsingDatabaseManager implementation
@@ -72,7 +73,9 @@
  protected:
   // Construct V4LocalDatabaseManager.
   // Must be initialized by calling StartOnIOThread() before using.
-  V4LocalDatabaseManager(const base::FilePath& base_path);
+  V4LocalDatabaseManager(
+      const base::FilePath& base_path,
+      ExtendedReportingLevelCallback extended_reporting_level_callback);
 
   ~V4LocalDatabaseManager() override;
 
@@ -265,6 +268,10 @@
   // ready to process next update.
   DatabaseUpdatedCallback db_updated_callback_;
 
+  // Callback to get the current extended reporting level. Needed by the update
+  // manager.
+  ExtendedReportingLevelCallback extended_reporting_level_callback_;
+
   // The list of stores to manage (for hash prefixes and full hashes). Each
   // element contains the identifier for the store, the corresponding
   // SBThreatType, whether to fetch hash prefixes for that store, and the
diff --git a/components/safe_browsing_db/v4_local_database_manager_unittest.cc b/components/safe_browsing_db/v4_local_database_manager_unittest.cc
index 85df2f85..2a1b2460 100644
--- a/components/safe_browsing_db/v4_local_database_manager_unittest.cc
+++ b/components/safe_browsing_db/v4_local_database_manager_unittest.cc
@@ -20,6 +20,8 @@
 
 namespace {
 
+typedef base::Callback<void()> NullCallback;
+
 // Utility function for populating hashes.
 FullHash HashForUrl(const GURL& url) {
   std::vector<FullHash> full_hashes;
@@ -188,8 +190,10 @@
     perform_full_hash_check_called_ = true;
   }
 
-  FakeV4LocalDatabaseManager(const base::FilePath& base_path)
-      : V4LocalDatabaseManager(base_path),
+  FakeV4LocalDatabaseManager(
+      const base::FilePath& base_path,
+      ExtendedReportingLevelCallback extended_reporting_level_callback)
+      : V4LocalDatabaseManager(base_path, extended_reporting_level_callback),
         perform_full_hash_check_called_(false) {}
 
   static bool PerformFullHashCheckCalled(
@@ -215,8 +219,13 @@
     ASSERT_TRUE(base_dir_.CreateUniqueTempDir());
     DVLOG(1) << "base_dir_: " << base_dir_.GetPath().value();
 
-    v4_local_database_manager_ =
-        make_scoped_refptr(new V4LocalDatabaseManager(base_dir_.GetPath()));
+    extended_reporting_level_ = SBER_LEVEL_OFF;
+    erl_callback_ =
+        base::Bind(&V4LocalDatabaseManagerTest::GetExtendedReportingLevel,
+                   base::Unretained(this));
+
+    v4_local_database_manager_ = make_scoped_refptr(
+        new V4LocalDatabaseManager(base_dir_.GetPath(), erl_callback_));
     SetTaskRunnerForTest();
 
     StartLocalDatabaseManager();
@@ -240,6 +249,10 @@
     return v4_local_database_manager_->queued_checks_;
   }
 
+  ExtendedReportingLevel GetExtendedReportingLevel() {
+    return extended_reporting_level_;
+  }
+
   void ReplaceV4Database(const StoreAndHashPrefixes& store_and_hash_prefixes,
                          bool stores_available = false) {
     // Disable the V4LocalDatabaseManager first so that if the callback to
@@ -264,8 +277,8 @@
 
   void ResetLocalDatabaseManager() {
     StopLocalDatabaseManager();
-    v4_local_database_manager_ =
-        make_scoped_refptr(new V4LocalDatabaseManager(base_dir_.GetPath()));
+    v4_local_database_manager_ = make_scoped_refptr(
+        new V4LocalDatabaseManager(base_dir_.GetPath(), erl_callback_));
     SetTaskRunnerForTest();
     StartLocalDatabaseManager();
   }
@@ -304,14 +317,16 @@
     // StopLocalDatabaseManager before resetting it because that's what
     // ~V4LocalDatabaseManager expects.
     StopLocalDatabaseManager();
-    v4_local_database_manager_ =
-        make_scoped_refptr(new FakeV4LocalDatabaseManager(base_dir_.GetPath()));
+    v4_local_database_manager_ = make_scoped_refptr(
+        new FakeV4LocalDatabaseManager(base_dir_.GetPath(), erl_callback_));
     SetTaskRunnerForTest();
     StartLocalDatabaseManager();
     WaitForTasksOnTaskRunner();
   }
 
   base::ScopedTempDir base_dir_;
+  ExtendedReportingLevel extended_reporting_level_;
+  ExtendedReportingLevelCallback erl_callback_;
   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
   content::TestBrowserThreadBundle thread_bundle_;
   scoped_refptr<V4LocalDatabaseManager> v4_local_database_manager_;
diff --git a/components/safe_browsing_db/v4_update_protocol_manager.cc b/components/safe_browsing_db/v4_update_protocol_manager.cc
index 43c3c25..e72eb44 100644
--- a/components/safe_browsing_db/v4_update_protocol_manager.cc
+++ b/components/safe_browsing_db/v4_update_protocol_manager.cc
@@ -73,6 +73,21 @@
 // Maximum time, in seconds, to wait for a response to an update request.
 static const int kV4TimerUpdateWaitSecMax = 30;
 
+ChromeClientInfo::SafeBrowsingReportingPopulation GetReportingLevelProtoValue(
+    ExtendedReportingLevel reporting_level) {
+  switch (reporting_level) {
+    case SBER_LEVEL_OFF:
+      return ChromeClientInfo::OPT_OUT;
+    case SBER_LEVEL_LEGACY:
+      return ChromeClientInfo::EXTENDED;
+    case SBER_LEVEL_SCOUT:
+      return ChromeClientInfo::SCOUT;
+    default:
+      NOTREACHED() << "Unexpected reporting_level!";
+      return ChromeClientInfo::UNSPECIFIED;
+  }
+}
+
 // The default V4UpdateProtocolManagerFactory.
 class V4UpdateProtocolManagerFactoryImpl
     : public V4UpdateProtocolManagerFactory {
@@ -82,9 +97,12 @@
   std::unique_ptr<V4UpdateProtocolManager> CreateProtocolManager(
       net::URLRequestContextGetter* request_context_getter,
       const V4ProtocolConfig& config,
-      V4UpdateCallback callback) override {
-    return std::unique_ptr<V4UpdateProtocolManager>(
-        new V4UpdateProtocolManager(request_context_getter, config, callback));
+      V4UpdateCallback update_callback,
+      ExtendedReportingLevelCallback extended_reporting_level_callback)
+      override {
+    return std::unique_ptr<V4UpdateProtocolManager>(new V4UpdateProtocolManager(
+        request_context_getter, config, update_callback,
+        extended_reporting_level_callback));
   }
 
  private:
@@ -100,12 +118,14 @@
 std::unique_ptr<V4UpdateProtocolManager> V4UpdateProtocolManager::Create(
     net::URLRequestContextGetter* request_context_getter,
     const V4ProtocolConfig& config,
-    V4UpdateCallback callback) {
+    V4UpdateCallback update_callback,
+    ExtendedReportingLevelCallback extended_reporting_level_callback) {
   if (!factory_) {
     factory_ = new V4UpdateProtocolManagerFactoryImpl();
   }
   return factory_->CreateProtocolManager(request_context_getter, config,
-                                         callback);
+                                         update_callback,
+                                         extended_reporting_level_callback);
 }
 
 void V4UpdateProtocolManager::ResetUpdateErrors() {
@@ -116,7 +136,8 @@
 V4UpdateProtocolManager::V4UpdateProtocolManager(
     net::URLRequestContextGetter* request_context_getter,
     const V4ProtocolConfig& config,
-    V4UpdateCallback update_callback)
+    V4UpdateCallback update_callback,
+    ExtendedReportingLevelCallback extended_reporting_level_callback)
     : update_error_count_(0),
       update_back_off_mult_(1),
       next_update_interval_(base::TimeDelta::FromSeconds(
@@ -125,7 +146,8 @@
       config_(config),
       request_context_getter_(request_context_getter),
       url_fetcher_id_(0),
-      update_callback_(update_callback) {
+      update_callback_(update_callback),
+      extended_reporting_level_callback_(extended_reporting_level_callback) {
   // Do not auto-schedule updates. Let the owner (V4LocalDatabaseManager) do it
   // when it is ready to process updates.
 }
@@ -217,6 +239,11 @@
         RICE);
   }
 
+  if (!extended_reporting_level_callback_.is_null()) {
+    request.mutable_chrome_client_info()->set_reporting_population(
+        GetReportingLevelProtoValue(extended_reporting_level_callback_.Run()));
+  }
+
   V4ProtocolManagerUtil::SetClientInfoFromConfig(request.mutable_client(),
                                                  config_);
 
diff --git a/components/safe_browsing_db/v4_update_protocol_manager.h b/components/safe_browsing_db/v4_update_protocol_manager.h
index a3b4cd5..4405742 100644
--- a/components/safe_browsing_db/v4_update_protocol_manager.h
+++ b/components/safe_browsing_db/v4_update_protocol_manager.h
@@ -21,6 +21,7 @@
 #include "base/threading/non_thread_safe.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
+#include "components/safe_browsing_db/safe_browsing_prefs.h"
 #include "components/safe_browsing_db/safebrowsing.pb.h"
 #include "components/safe_browsing_db/util.h"
 #include "components/safe_browsing_db/v4_protocol_manager_util.h"
@@ -44,6 +45,8 @@
 typedef base::Callback<void(std::unique_ptr<ParsedServerResponse>)>
     V4UpdateCallback;
 
+typedef base::Callback<ExtendedReportingLevel()> ExtendedReportingLevelCallback;
+
 class V4UpdateProtocolManager : public net::URLFetcherDelegate,
                                 public base::NonThreadSafe {
  public:
@@ -59,7 +62,8 @@
   static std::unique_ptr<V4UpdateProtocolManager> Create(
       net::URLRequestContextGetter* request_context_getter,
       const V4ProtocolConfig& config,
-      V4UpdateCallback callback);
+      V4UpdateCallback update_callback,
+      ExtendedReportingLevelCallback extended_reporting_level_callback);
 
   // net::URLFetcherDelegate interface.
   void OnURLFetchComplete(const net::URLFetcher* source) override;
@@ -75,7 +79,8 @@
   V4UpdateProtocolManager(
       net::URLRequestContextGetter* request_context_getter,
       const V4ProtocolConfig& config,
-      V4UpdateCallback callback);
+      V4UpdateCallback update_callback,
+      ExtendedReportingLevelCallback extended_reporting_level_callback);
 
  private:
   FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest,
@@ -90,6 +95,8 @@
   FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest, TestDisableAutoUpdates);
   FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest,
                            TestGetUpdatesHasTimeout);
+  FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest,
+                           TestExtendedReportingLevelIncluded);
   friend class V4UpdateProtocolManagerFactoryImpl;
 
   // Fills a FetchThreatListUpdatesRequest protocol buffer for a request.
@@ -183,6 +190,8 @@
   // complete.
   base::OneShotTimer timeout_timer_;
 
+  ExtendedReportingLevelCallback extended_reporting_level_callback_;
+
   DISALLOW_COPY_AND_ASSIGN(V4UpdateProtocolManager);
 };
 
@@ -194,7 +203,8 @@
   virtual std::unique_ptr<V4UpdateProtocolManager> CreateProtocolManager(
       net::URLRequestContextGetter* request_context_getter,
       const V4ProtocolConfig& config,
-      V4UpdateCallback callback) = 0;
+      V4UpdateCallback update_callback,
+      ExtendedReportingLevelCallback extended_reporting_level_callback) = 0;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(V4UpdateProtocolManagerFactory);
diff --git a/components/safe_browsing_db/v4_update_protocol_manager_unittest.cc b/components/safe_browsing_db/v4_update_protocol_manager_unittest.cc
index cdef738..e76e249 100644
--- a/components/safe_browsing_db/v4_update_protocol_manager_unittest.cc
+++ b/components/safe_browsing_db/v4_update_protocol_manager_unittest.cc
@@ -58,13 +58,20 @@
     }
   }
 
+  ExtendedReportingLevel GetExtendedReportingLevel(ExtendedReportingLevel erl) {
+    return erl;
+  }
+
   std::unique_ptr<V4UpdateProtocolManager> CreateProtocolManager(
       const std::vector<ListUpdateResponse>& expected_lurs,
-      bool disable_auto_update = false) {
+      bool disable_auto_update = false,
+      ExtendedReportingLevel erl = SBER_LEVEL_OFF) {
     return V4UpdateProtocolManager::Create(
         NULL, GetTestV4ProtocolConfig(disable_auto_update),
         base::Bind(&V4UpdateProtocolManagerTest::ValidateGetUpdatesResults,
-                   base::Unretained(this), expected_lurs));
+                   base::Unretained(this), expected_lurs),
+        base::Bind(&V4UpdateProtocolManagerTest::GetExtendedReportingLevel,
+                   base::Unretained(this), erl));
   }
 
   void SetupStoreStates() {
@@ -291,7 +298,7 @@
 
   std::string encoded_request_with_minus =
       pm->GetBase64SerializedUpdateRequestProto();
-  EXPECT_EQ("Cg8KCHVuaXR0ZXN0EgMxLjAaGAgBEAIaCmg4eGZZcVk-OlIiBCABIAIoAQ==",
+  EXPECT_EQ("Cg8KCHVuaXR0ZXN0EgMxLjAaGAgBEAIaCmg4eGZZcVk-OlIiBCABIAIoASICCAE=",
             encoded_request_with_minus);
 
   // TODO(vakh): Add a similar test for underscore for completeness, although
@@ -358,4 +365,27 @@
   EXPECT_EQ(1ul, pm->update_back_off_mult_);
 }
 
+TEST_F(V4UpdateProtocolManagerTest, TestExtendedReportingLevelIncluded) {
+  store_state_map_->clear();
+  (*store_state_map_)[ListIdentifier(LINUX_PLATFORM, URL, MALWARE_THREAT)] =
+      "state";
+  std::string base = "Cg8KCHVuaXR0ZXN0EgMxLjAaEwgBEAIaBXN0YXRlIgQgASACKAEiAgg";
+
+  std::unique_ptr<V4UpdateProtocolManager> pm_with_off(CreateProtocolManager(
+      std::vector<ListUpdateResponse>({}), false, SBER_LEVEL_OFF));
+  pm_with_off->store_state_map_ = std::move(store_state_map_);
+  EXPECT_EQ(base + "B", pm_with_off->GetBase64SerializedUpdateRequestProto());
+
+  std::unique_ptr<V4UpdateProtocolManager> pm_with_legacy(CreateProtocolManager(
+      std::vector<ListUpdateResponse>({}), false, SBER_LEVEL_LEGACY));
+  pm_with_legacy->store_state_map_ = std::move(pm_with_off->store_state_map_);
+  EXPECT_EQ(base + "C",
+            pm_with_legacy->GetBase64SerializedUpdateRequestProto());
+
+  std::unique_ptr<V4UpdateProtocolManager> pm_with_scout(CreateProtocolManager(
+      std::vector<ListUpdateResponse>({}), false, SBER_LEVEL_SCOUT));
+  pm_with_scout->store_state_map_ = std::move(pm_with_legacy->store_state_map_);
+  EXPECT_EQ(base + "D", pm_with_scout->GetBase64SerializedUpdateRequestProto());
+}
+
 }  // namespace safe_browsing
diff --git a/components/sync/driver/data_type_manager.h b/components/sync/driver/data_type_manager.h
index b3d271e..91c65c58 100644
--- a/components/sync/driver/data_type_manager.h
+++ b/components/sync/driver/data_type_manager.h
@@ -50,6 +50,7 @@
     ConfigureStatus status;
     ModelTypeSet requested_types;
     DataTypeStatusTable data_type_status_table;
+    bool was_catch_up_configure = false;
   };
 
   virtual ~DataTypeManager() {}
@@ -88,6 +89,12 @@
   // stopped.
   virtual void Stop() = 0;
 
+  // Get the set of current active data types (those chosen or configured by the
+  // user which have not also encountered a runtime error). Note that during
+  // configuration, this will the the empty set. Once the configuration
+  // completes the set will be updated.
+  virtual ModelTypeSet GetActiveDataTypes() const = 0;
+
   // The current state of the data type manager.
   virtual State state() const = 0;
 };
diff --git a/components/sync/driver/data_type_manager_impl.cc b/components/sync/driver/data_type_manager_impl.cc
index afb73b0..59f3536 100644
--- a/components/sync/driver/data_type_manager_impl.cc
+++ b/components/sync/driver/data_type_manager_impl.cc
@@ -798,13 +798,14 @@
 }
 
 void DataTypeManagerImpl::NotifyDone(const ConfigureResult& raw_result) {
-  catch_up_in_progress_ = false;
-
   DCHECK(!last_restart_time_.is_null());
   base::TimeDelta configure_time = base::Time::Now() - last_restart_time_;
 
   ConfigureResult result = raw_result;
   result.data_type_status_table = data_type_status_table_;
+  result.was_catch_up_configure = catch_up_in_progress_;
+
+  catch_up_in_progress_ = false;
 
   DVLOG(1) << "Total time spent configuring: " << configure_time.InSecondsF()
            << "s";
@@ -837,6 +838,12 @@
   observer_->OnConfigureDone(result);
 }
 
+ModelTypeSet DataTypeManagerImpl::GetActiveDataTypes() const {
+  if (state_ != CONFIGURED)
+    return ModelTypeSet();
+  return GetEnabledTypes();
+}
+
 DataTypeManager::State DataTypeManagerImpl::state() const {
   return state_;
 }
diff --git a/components/sync/driver/data_type_manager_impl.h b/components/sync/driver/data_type_manager_impl.h
index cf28cdf..3261e04 100644
--- a/components/sync/driver/data_type_manager_impl.h
+++ b/components/sync/driver/data_type_manager_impl.h
@@ -56,6 +56,7 @@
                          ConfigureReason reason) override;
 
   void Stop() override;
+  ModelTypeSet GetActiveDataTypes() const override;
   State state() const override;
 
   // |ModelAssociationManagerDelegate| implementation.
diff --git a/components/sync/driver/data_type_manager_mock.h b/components/sync/driver/data_type_manager_mock.h
index fe7688d..19467ec5 100644
--- a/components/sync/driver/data_type_manager_mock.h
+++ b/components/sync/driver/data_type_manager_mock.h
@@ -22,6 +22,7 @@
   MOCK_METHOD2(PurgeForMigration, void(ModelTypeSet, ConfigureReason));
   MOCK_METHOD0(Stop, void());
   MOCK_METHOD0(controllers, const DataTypeController::TypeMap&());
+  MOCK_CONST_METHOD0(GetActiveDataTypes, ModelTypeSet());
   MOCK_CONST_METHOD0(state, State());
 
  private:
diff --git a/components/sync/protocol/printer_specifics.proto b/components/sync/protocol/printer_specifics.proto
index a42a815..e0881b7 100644
--- a/components/sync/protocol/printer_specifics.proto
+++ b/components/sync/protocol/printer_specifics.proto
@@ -53,4 +53,7 @@
 
   // Structure representing the user's ppd configuration.
   optional PrinterPPDReference ppd_reference = 9;
+
+  // Timestamp when printer was last updated.
+  optional int64 updated_timestamp = 10;
 }
diff --git a/components/sync_sessions/sessions_sync_manager.cc b/components/sync_sessions/sessions_sync_manager.cc
index 4b0938e..471e9eb 100644
--- a/components/sync_sessions/sessions_sync_manager.cc
+++ b/components/sync_sessions/sessions_sync_manager.cc
@@ -7,9 +7,12 @@
 #include <algorithm>
 #include <utility>
 
+#include "base/format_macros.h"
+#include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/strings/stringprintf.h"
 #include "build/build_config.h"
 #include "components/sync/base/hash_util.h"
 #include "components/sync/device_info/local_device_info_provider.h"
@@ -21,6 +24,7 @@
 #include "components/sync_sessions/synced_tab_delegate.h"
 #include "components/sync_sessions/synced_window_delegate.h"
 #include "components/sync_sessions/synced_window_delegates_getter.h"
+#include "components/sync_sessions/tab_node_pool.h"
 #include "components/variations/variations_associated_data.h"
 
 using sessions::SerializedNavigationEntry;
@@ -62,17 +66,44 @@
   return s1->modified_time > s2->modified_time;
 }
 
+std::string TabNodeIdToTag(const std::string& machine_tag, int tab_node_id) {
+  CHECK_GT(tab_node_id, TabNodePool::kInvalidTabNodeID) << "crbug.com/673618";
+  return base::StringPrintf("%s %d", machine_tag.c_str(), tab_node_id);
+}
+
 std::string TagFromSpecifics(const sync_pb::SessionSpecifics& specifics) {
   if (specifics.has_header()) {
     return specifics.session_tag();
   } else if (specifics.has_tab()) {
-    return TabNodePool::TabIdToTag(specifics.session_tag(),
-                                   specifics.tab_node_id());
+    return TabNodeIdToTag(specifics.session_tag(), specifics.tab_node_id());
   } else {
     return std::string();
   }
 }
 
+sync_pb::SessionSpecifics SessionTabToSpecifics(
+    const sessions::SessionTab& session_tab,
+    const std::string& local_tag,
+    int tab_node_id) {
+  sync_pb::SessionSpecifics specifics;
+  specifics.mutable_tab()->CopyFrom(session_tab.ToSyncData());
+  specifics.set_session_tag(local_tag);
+  specifics.set_tab_node_id(tab_node_id);
+  return specifics;
+}
+
+void AppendDeletionsForTabNodes(const std::set<int>& tab_node_ids,
+                                const std::string& machine_tag,
+                                syncer::SyncChangeList* change_output) {
+  for (std::set<int>::const_iterator it = tab_node_ids.begin();
+       it != tab_node_ids.end(); ++it) {
+    change_output->push_back(syncer::SyncChange(
+        FROM_HERE, SyncChange::ACTION_DELETE,
+        SyncData::CreateLocalDelete(TabNodeIdToTag(machine_tag, *it),
+                                    syncer::SESSIONS)));
+  }
+}
+
 }  // namespace
 
 // |local_device| is owned by ProfileSyncService, its lifetime exceeds
@@ -117,7 +148,6 @@
     std::unique_ptr<syncer::SyncErrorFactory> error_handler) {
   syncer::SyncMergeResult merge_result(type);
   DCHECK(session_tracker_.Empty());
-  DCHECK_EQ(0U, local_tab_pool_.Capacity());
 
   error_handler_ = std::move(error_handler);
   sync_processor_ = std::move(sync_processor);
@@ -153,13 +183,12 @@
     InitializeCurrentMachineTag(local_device_->GetLocalSyncCacheGUID());
   }
 
-  session_tracker_.SetLocalSessionTag(current_machine_tag_);
+  session_tracker_.SetLocalSessionTag(current_machine_tag());
 
   syncer::SyncChangeList new_changes;
 
   // First, we iterate over sync data to update our session_tracker_.
-  syncer::SyncDataList restored_tabs;
-  if (!InitFromSyncModel(initial_sync_data, &restored_tabs, &new_changes)) {
+  if (!InitFromSyncModel(initial_sync_data, &new_changes)) {
     // The sync db didn't have a header node for us. Create one.
     sync_pb::EntitySpecifics specifics;
     sync_pb::SessionSpecifics* base_specifics = specifics.mutable_session();
@@ -176,12 +205,12 @@
 #if defined(OS_ANDROID)
   std::string sync_machine_tag(
       BuildMachineTag(local_device_->GetLocalSyncCacheGUID()));
-  if (current_machine_tag_.compare(sync_machine_tag) != 0)
+  if (current_machine_tag().compare(sync_machine_tag) != 0)
     DeleteForeignSessionInternal(sync_machine_tag, &new_changes);
 #endif
 
   // Check if anything has changed on the local client side.
-  AssociateWindows(RELOAD_TABS, restored_tabs, &new_changes);
+  AssociateWindows(RELOAD_TABS, &new_changes);
   local_tab_pool_out_of_sync_ = false;
 
   merge_result.set_error(
@@ -193,7 +222,6 @@
 
 void SessionsSyncManager::AssociateWindows(
     ReloadTabsOption option,
-    const syncer::SyncDataList& restored_tabs,
     syncer::SyncChangeList* change_output) {
   const std::string local_tag = current_machine_tag();
   sync_pb::SessionSpecifics specifics;
@@ -261,24 +289,23 @@
         if (!synced_tab)
           continue;
 
+        // Placeholder tabs are those without WebContents, either because they
+        // were never loaded into memory or they were evicted from memory
+        // (typically only on Android devices). They only have a tab id, window
+        // id, and a saved synced id (corresponding to the tab node id). Note
+        // that only placeholders have this sync id, as it's necessary to
+        // properly reassociate the tab with the entity that was backing it.
         if (synced_tab->IsPlaceholderTab()) {
           // For tabs without WebContents update the |tab_id| and |window_id|,
           // as it could have changed after a session restore.
-          // Note: We cannot check if a tab is valid if it has no WebContents.
-          // We assume any such tab is valid and leave the contents of
-          // corresponding sync node unchanged.
           if (synced_tab->GetSyncId() > TabNodePool::kInvalidTabNodeID &&
               tab_id > TabNodePool::kInvalidTabID) {
             AssociateRestoredPlaceholderTab(*synced_tab, tab_id, window_id,
-                                            restored_tabs, change_output);
-            found_tabs = true;
-            window_s.add_tab(tab_id);
+                                            change_output);
           }
-          continue;
-        }
-
-        if (RELOAD_TABS == option)
+        } else if (RELOAD_TABS == option) {
           AssociateTab(synced_tab, change_output);
+        }
 
         // If the tab is valid, it would have been added to the tracker either
         // by the above AssociateTab call (at association time), or by the
@@ -303,8 +330,10 @@
       }
     }
   }
-  local_tab_pool_.DeleteUnassociatedTabNodes(change_output);
-  session_tracker_.CleanupSession(local_tag);
+  std::set<int> deleted_tab_node_ids;
+  session_tracker_.CleanupLocalTabs(&deleted_tab_node_ids);
+  AppendDeletionsForTabNodes(deleted_tab_node_ids, current_machine_tag(),
+                             change_output);
 
   // Always update the header.  Sync takes care of dropping this update
   // if the entity specifics are identical (i.e windows, client name did
@@ -317,73 +346,63 @@
       syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE, data));
 }
 
-void SessionsSyncManager::AssociateTab(SyncedTabDelegate* const tab,
+void SessionsSyncManager::AssociateTab(SyncedTabDelegate* const tab_delegate,
                                        syncer::SyncChangeList* change_output) {
-  DCHECK(!tab->IsPlaceholderTab());
-  SessionID::id_type tab_id = tab->GetSessionId();
+  DCHECK(!tab_delegate->IsPlaceholderTab());
 
-  if (tab->IsBeingDestroyed()) {
-    // This tab is closing.
-    TabLinksMap::iterator tab_iter = local_tab_map_.find(tab_id);
-    if (tab_iter == local_tab_map_.end()) {
-      // We aren't tracking this tab (for example, sync setting page).
-      return;
-    }
-    local_tab_pool_.FreeTabNode(tab_iter->second->tab_node_id(), change_output);
-    local_tab_map_.erase(tab_iter);
+  if (tab_delegate->IsBeingDestroyed()) {
+    // Do nothing. By not proactively adding the tab to the session, it will be
+    // removed if necessary during subsequent cleanup.
     return;
   }
 
-  if (!tab->ShouldSync(sessions_client_))
+  if (!tab_delegate->ShouldSync(sessions_client_))
     return;
 
-  TabLinksMap::iterator local_tab_map_iter = local_tab_map_.find(tab_id);
-  TabLink* tab_link = nullptr;
+  SessionID::id_type tab_id = tab_delegate->GetSessionId();
+  DVLOG(1) << "Syncing tab " << tab_id << " from window "
+           << tab_delegate->GetWindowId();
 
-  if (local_tab_map_iter == local_tab_map_.end()) {
-    int tab_node_id = tab->GetSyncId();
-    // If there is an old sync node for the tab, reuse it.  If this is a new
-    // tab, get a sync node for it.
-    if (!local_tab_pool_.IsUnassociatedTabNode(tab_node_id)) {
-      tab_node_id = local_tab_pool_.GetFreeTabNode(change_output);
-      tab->SetSyncId(tab_node_id);
-    }
-    local_tab_pool_.AssociateTabNode(tab_node_id, tab_id);
-    tab_link = new TabLink(tab_node_id, tab);
-    local_tab_map_[tab_id] = make_linked_ptr<TabLink>(tab_link);
-  } else {
-    // This tab is already associated with a sync node, reuse it.
-    // Note: on some platforms the tab object may have changed, so we ensure
-    // the tab link is up to date.
-    tab_link = local_tab_map_iter->second.get();
-    local_tab_map_iter->second->set_tab(tab);
-  }
-  DCHECK(tab_link);
-  DCHECK_NE(tab_link->tab_node_id(), TabNodePool::kInvalidTabNodeID);
-  DVLOG(1) << "Reloading tab " << tab_id << " from window "
-           << tab->GetWindowId();
+  int tab_node_id = TabNodePool::kInvalidTabNodeID;
+  bool existing_tab_node =
+      session_tracker_.GetTabNodeFromLocalTabId(tab_id, &tab_node_id);
+  CHECK_NE(TabNodePool::kInvalidTabNodeID, tab_node_id) << "crbug.com/673618";
+  tab_delegate->SetSyncId(tab_node_id);
+  sessions::SessionTab* session_tab =
+      session_tracker_.GetTab(current_machine_tag(), tab_id);
 
-  // Write to sync model.
-  sync_pb::EntitySpecifics specifics;
-  LocalTabDelegateToSpecifics(*tab, specifics.mutable_session());
-  syncer::SyncData data = syncer::SyncData::CreateLocalData(
-      TabNodePool::TabIdToTag(current_machine_tag_, tab_link->tab_node_id()),
-      current_session_name_, specifics);
-  change_output->push_back(
-      syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE, data));
+  // Get the previously synced url.
+  int old_index = session_tab->normalized_navigation_index();
+  GURL old_url;
+  if (session_tab->navigations.size() > static_cast<size_t>(old_index))
+    old_url = session_tab->navigations[old_index].virtual_url();
 
-  int current_index = tab->GetCurrentEntryIndex();
-  const GURL new_url = tab->GetVirtualURLAtIndex(current_index);
-  if (new_url != tab_link->url()) {
-    tab_link->set_url(new_url);
-    favicon_cache_.OnFaviconVisited(new_url,
-                                    tab->GetFaviconURLAtIndex(current_index));
-    page_revisit_broadcaster_.OnPageVisit(
-        new_url, tab->GetTransitionAtIndex(current_index));
-  }
-
+  // Update the tracker's session representation.
+  SetSessionTabFromDelegate(*tab_delegate, base::Time::Now(), session_tab);
+  SetVariationIds(session_tab);
   session_tracker_.GetSession(current_machine_tag())->modified_time =
       base::Time::Now();
+
+  // Write to the sync model itself.
+  sync_pb::EntitySpecifics specifics;
+  specifics.mutable_session()->CopyFrom(
+      SessionTabToSpecifics(*session_tab, current_machine_tag(), tab_node_id));
+  syncer::SyncData data = syncer::SyncData::CreateLocalData(
+      TabNodeIdToTag(current_machine_tag(), tab_node_id), current_session_name_,
+      specifics);
+  change_output->push_back(syncer::SyncChange(
+      FROM_HERE, existing_tab_node ? syncer::SyncChange::ACTION_UPDATE
+                                   : syncer::SyncChange::ACTION_ADD,
+      data));
+
+  int current_index = tab_delegate->GetCurrentEntryIndex();
+  const GURL new_url = tab_delegate->GetVirtualURLAtIndex(current_index);
+  if (new_url != old_url) {
+    favicon_cache_.OnFaviconVisited(
+        new_url, tab_delegate->GetFaviconURLAtIndex(current_index));
+    page_revisit_broadcaster_.OnPageVisit(
+        new_url, tab_delegate->GetTransitionAtIndex(current_index));
+  }
 }
 
 bool SessionsSyncManager::RebuildAssociations() {
@@ -443,21 +462,14 @@
   // "interesting" by going to a valid URL, in which case it needs to be added
   // to the window's tab information. Similarly, if a tab became
   // "uninteresting", we remove it from the window's tab information.
-  AssociateWindows(DONT_RELOAD_TABS, syncer::SyncDataList(), &changes);
+  AssociateWindows(DONT_RELOAD_TABS, &changes);
   sync_processor_->ProcessSyncChanges(FROM_HERE, changes);
 }
 
 void SessionsSyncManager::OnFaviconsChanged(const std::set<GURL>& page_urls,
                                             const GURL& /* icon_url */) {
-  // TODO(zea): consider a separate container for tabs with outstanding favicon
-  // loads so we don't have to iterate through all tabs comparing urls.
-  for (const GURL& page_url : page_urls) {
-    for (TabLinksMap::iterator tab_iter = local_tab_map_.begin();
-         tab_iter != local_tab_map_.end(); ++tab_iter) {
-      if (tab_iter->second->url() == page_url)
-        favicon_cache_.OnPageFaviconUpdated(page_url);
-    }
-  }
+  for (const GURL& page_url : page_urls)
+    favicon_cache_.OnPageFaviconUpdated(page_url);
 }
 
 void SessionsSyncManager::StopSyncing(syncer::ModelType type) {
@@ -470,8 +482,6 @@
   sync_processor_.reset(nullptr);
   error_handler_.reset();
   session_tracker_.Clear();
-  local_tab_map_.clear();
-  local_tab_pool_.Clear();
   current_machine_tag_.clear();
   current_session_name_.clear();
   local_session_header_node_id_ = TabNodePool::kInvalidTabNodeID;
@@ -494,22 +504,17 @@
       current_machine_tag(), current_session_name_, header_entity);
   list.push_back(data);
 
-  for (auto win_iter = session->windows.begin();
-       win_iter != session->windows.end(); ++win_iter) {
-    for (auto tabs_iter = win_iter->second->tabs.begin();
-         tabs_iter != win_iter->second->tabs.end(); ++tabs_iter) {
+  for (auto& win_iter : session->windows) {
+    for (auto& tab : win_iter.second->tabs) {
+      // TODO(zea): replace with with the correct tab node id once there's a
+      // sync specific wrapper for SessionTab. This method is only used in
+      // tests though, so it's fine for now. crbug.com/662597
+      int tab_node_id = 0;
       sync_pb::EntitySpecifics entity;
-      sync_pb::SessionSpecifics* specifics = entity.mutable_session();
-      specifics->mutable_tab()->MergeFrom((*tabs_iter)->ToSyncData());
-      specifics->set_session_tag(current_machine_tag_);
-
-      TabLinksMap::const_iterator tab_map_iter =
-          local_tab_map_.find((*tabs_iter)->tab_id.id());
-      DCHECK(tab_map_iter != local_tab_map_.end());
-      specifics->set_tab_node_id(tab_map_iter->second->tab_node_id());
+      entity.mutable_session()->CopyFrom(
+          SessionTabToSpecifics(*tab, current_machine_tag(), tab_node_id));
       syncer::SyncData data = syncer::SyncData::CreateLocalData(
-          TabNodePool::TabIdToTag(current_machine_tag_,
-                                  specifics->tab_node_id()),
+          TabNodeIdToTag(current_machine_tag(), tab_node_id),
           current_session_name_, entity);
       list.push_back(data);
     }
@@ -518,7 +523,7 @@
 }
 
 bool SessionsSyncManager::GetLocalSession(const SyncedSession** local_session) {
-  if (current_machine_tag_.empty())
+  if (current_machine_tag().empty())
     return false;
   *local_session = session_tracker_.GetSession(current_machine_tag());
   return true;
@@ -578,7 +583,7 @@
           LOG(WARNING) << "Dropping modification to local session.";
           return syncer::SyncError();
         }
-        UpdateTrackerWithForeignSession(
+        UpdateTrackerWithSpecifics(
             session, syncer::SyncDataRemote(it->sync_data()).GetModifiedTime());
         break;
       default:
@@ -600,7 +605,7 @@
     return syncer::SyncChange(
         FROM_HERE, SyncChange::ACTION_DELETE,
         SyncData::CreateLocalDelete(
-            TabNodePool::TabIdToTag(current_machine_tag(), tab.tab_node_id()),
+            TabNodeIdToTag(current_machine_tag(), tab.tab_node_id()),
             syncer::SESSIONS));
   }
 }
@@ -616,7 +621,6 @@
 
 bool SessionsSyncManager::InitFromSyncModel(
     const syncer::SyncDataList& sync_data,
-    syncer::SyncDataList* restored_tabs,
     syncer::SyncChangeList* new_changes) {
   bool found_current_header = false;
   int bad_foreign_hash_count = 0;
@@ -634,7 +638,7 @@
         new_changes->push_back(tombstone);
     } else if (specifics.session_tag() != current_machine_tag()) {
       if (TagHashFromSpecifics(specifics) == remote.GetClientTagHash()) {
-        UpdateTrackerWithForeignSession(specifics, remote.GetModifiedTime());
+        UpdateTrackerWithSpecifics(specifics, remote.GetModifiedTime());
       } else {
         // In the past, like years ago, we believe that some session data was
         // created with bad tag hashes. This causes any change this client makes
@@ -653,6 +657,10 @@
         found_current_header = true;
         if (specifics.header().has_client_name())
           current_session_name_ = specifics.header().client_name();
+
+        // TODO(zea): crbug.com/639009 update the tracker with the specifics
+        // from the header node as well. This will be necessary to preserve
+        // the set of open tabs when a custom tab is opened.
       } else {
         if (specifics.has_header() || !specifics.has_tab()) {
           LOG(WARNING) << "Found more than one session header node with local "
@@ -661,10 +669,13 @@
           if (tombstone.IsValid())
             new_changes->push_back(tombstone);
         } else {
-          // This is a valid old tab node, add it to the pool so it can be
-          // reused for reassociation.
-          local_tab_pool_.AddTabNode(specifics.tab_node_id());
-          restored_tabs->push_back(*it);
+          // This is a valid old tab node, add it to the tracker and associate
+          // it.
+          DVLOG(1) << "Associating local tab " << specifics.tab().tab_id()
+                   << " with node " << specifics.tab_node_id();
+          session_tracker_.ReassociateLocalTab(specifics.tab_node_id(),
+                                               specifics.tab().tab_id());
+          UpdateTrackerWithSpecifics(specifics, remote.GetModifiedTime());
         }
       }
     }
@@ -676,7 +687,7 @@
   session_tracker_.LookupAllForeignSessions(&sessions,
                                             SyncedSessionTracker::RAW);
   for (const auto* session : sessions) {
-    session_tracker_.CleanupSession(session->session_tag);
+    session_tracker_.CleanupForeignSession(session->session_tag);
   }
 
   UMA_HISTOGRAM_COUNTS_100("Sync.SessionsBadForeignHashOnMergeCount",
@@ -685,70 +696,84 @@
   return found_current_header;
 }
 
-void SessionsSyncManager::UpdateTrackerWithForeignSession(
+void SessionsSyncManager::UpdateTrackerWithSpecifics(
     const sync_pb::SessionSpecifics& specifics,
     const base::Time& modification_time) {
-  std::string foreign_session_tag = specifics.session_tag();
-  DCHECK_NE(foreign_session_tag, current_machine_tag());
-
-  SyncedSession* foreign_session =
-      session_tracker_.GetSession(foreign_session_tag);
+  std::string session_tag = specifics.session_tag();
+  SyncedSession* session = session_tracker_.GetSession(session_tag);
   if (specifics.has_header()) {
-    // Read in the header data for this foreign session. Header data is
+    // Read in the header data for this session. Header data is
     // essentially a collection of windows, each of which has an ordered id list
     // for their tabs.
 
     if (!IsValidSessionHeader(specifics.header())) {
-      LOG(WARNING) << "Ignoring foreign session node with invalid header "
-                   << "and tag " << foreign_session_tag << ".";
+      LOG(WARNING) << "Ignoring session node with invalid header "
+                   << "and tag " << session_tag << ".";
       return;
     }
 
     // Load (or create) the SyncedSession object for this client.
     const sync_pb::SessionHeader& header = specifics.header();
-    PopulateSessionHeaderFromSpecifics(header, modification_time,
-                                       foreign_session);
+    PopulateSessionHeaderFromSpecifics(header, modification_time, session);
 
     // Reset the tab/window tracking for this session (must do this before
     // we start calling PutWindowInSession and PutTabInWindow so that all
     // unused tabs/windows get cleared by the CleanupSession(...) call).
-    session_tracker_.ResetSessionTracking(foreign_session_tag);
+    session_tracker_.ResetSessionTracking(session_tag);
 
     // Process all the windows and their tab information.
     int num_windows = header.window_size();
-    DVLOG(1) << "Associating " << foreign_session_tag << " with " << num_windows
+    DVLOG(1) << "Populating " << session_tag << " with " << num_windows
              << " windows.";
 
     for (int i = 0; i < num_windows; ++i) {
       const sync_pb::SessionWindow& window_s = header.window(i);
       SessionID::id_type window_id = window_s.window_id();
-      session_tracker_.PutWindowInSession(foreign_session_tag, window_id);
-      BuildSyncedSessionFromSpecifics(
-          foreign_session_tag, window_s, modification_time,
-          foreign_session->windows[window_id].get());
+      session_tracker_.PutWindowInSession(session_tag, window_id);
+      BuildSyncedSessionFromSpecifics(session_tag, window_s, modification_time,
+                                      session->windows[window_id].get());
     }
     // Delete any closed windows and unused tabs as necessary.
-    session_tracker_.CleanupSession(foreign_session_tag);
+    session_tracker_.CleanupForeignSession(session_tag);
   } else if (specifics.has_tab()) {
     const sync_pb::SessionTab& tab_s = specifics.tab();
     SessionID::id_type tab_id = tab_s.tab_id();
+    DVLOG(1) << "Populating " << session_tag << "'s tab id " << tab_id
+             << " from node " << specifics.tab_node_id();
 
-    const sessions::SessionTab* existing_tab;
-    if (session_tracker_.LookupSessionTab(foreign_session_tag, tab_id,
-                                          &existing_tab) &&
-        existing_tab->timestamp > modification_time) {
-      // Force the tracker to remember this tab node id, even if it isn't
-      // currently being used.
-      session_tracker_.GetTab(foreign_session_tag, tab_id,
-                              specifics.tab_node_id());
-      DVLOG(1) << "Ignoring " << foreign_session_tag << "'s session tab "
-               << tab_id << " with earlier modification time";
+    // Ensure the tracker is aware of the tab node id. Deleting foreign sessions
+    // requires deleting all relevant tab nodes, and it's easier to track the
+    // tab node ids themselves separately from the tab ids.
+    //
+    // Note that TabIDs are not stable across restarts of a client. Consider
+    // this example with two tabs:
+    //
+    // http://a.com  TabID1 --> NodeIDA
+    // http://b.com  TabID2 --> NodeIDB
+    //
+    // After restart, tab ids are reallocated. e.g, one possibility:
+    // http://a.com TabID2 --> NodeIDA
+    // http://b.com TabID1 --> NodeIDB
+    //
+    // If that happened on a remote client, here we will see an update to
+    // TabID1 with tab_node_id changing from NodeIDA to NodeIDB, and TabID2
+    // with tab_node_id changing from NodeIDB to NodeIDA.
+    //
+    // We can also wind up here if we created this tab as an out-of-order
+    // update to the header node for this session before actually associating
+    // the tab itself, so the tab node id wasn't available at the time and
+    // is currently kInvalidTabNodeID.
+    //
+    // In both cases, we can safely throw it into the set of node ids.
+    session_tracker_.OnTabNodeSeen(session_tag, specifics.tab_node_id());
+    sessions::SessionTab* tab = session_tracker_.GetTab(session_tag, tab_id);
+    if (!tab->timestamp.is_null() && tab->timestamp > modification_time) {
+      DVLOG(1) << "Ignoring " << session_tag << "'s session tab " << tab_id
+               << " with earlier modification time: " << tab->timestamp
+               << " vs " << modification_time;
       return;
     }
 
-    sessions::SessionTab* tab = session_tracker_.GetTab(
-        foreign_session_tag, tab_id, specifics.tab_node_id());
-
     // Update SessionTab based on protobuf.
     tab->SetFromSyncData(tab_s, modification_time);
 
@@ -757,11 +782,11 @@
     RefreshFaviconVisitTimesFromForeignTab(tab_s, modification_time);
 
     // Update the last modified time.
-    if (foreign_session->modified_time < modification_time)
-      foreign_session->modified_time = modification_time;
+    if (session->modified_time < modification_time)
+      session->modified_time = modification_time;
   } else {
-    LOG(WARNING) << "Ignoring foreign session node with missing header/tab "
-                 << "fields and tag " << foreign_session_tag << ".";
+    LOG(WARNING) << "Ignoring session node with missing header/tab "
+                 << "fields and tag " << session_tag << ".";
   }
 }
 
@@ -779,8 +804,6 @@
     DVLOG(1) << "Creating session sync guid: " << current_machine_tag_;
     sync_prefs_->SetSyncSessionsGUID(current_machine_tag_);
   }
-
-  local_tab_pool_.SetMachineTag(current_machine_tag_);
 }
 
 // static
@@ -844,11 +867,11 @@
     }
   }
   session_window->timestamp = mtime;
-  session_window->tabs.resize(specifics.tab_size());
+  session_window->tabs.clear();
   for (int i = 0; i < specifics.tab_size(); i++) {
     SessionID::id_type tab_id = specifics.tab(i);
     session_tracker_.PutTabInWindow(session_tag, session_window->window_id.id(),
-                                    tab_id, i);
+                                    tab_id);
   }
 }
 
@@ -890,20 +913,14 @@
   }
 
   std::set<int> tab_node_ids_to_delete;
-  session_tracker_.LookupTabNodeIds(tag, &tab_node_ids_to_delete);
+  session_tracker_.LookupForeignTabNodeIds(tag, &tab_node_ids_to_delete);
   if (DisassociateForeignSession(tag)) {
     // Only tell sync to delete the header if there was one.
     change_output->push_back(
         syncer::SyncChange(FROM_HERE, SyncChange::ACTION_DELETE,
                            SyncData::CreateLocalDelete(tag, syncer::SESSIONS)));
   }
-  for (std::set<int>::const_iterator it = tab_node_ids_to_delete.begin();
-       it != tab_node_ids_to_delete.end(); ++it) {
-    change_output->push_back(syncer::SyncChange(
-        FROM_HERE, SyncChange::ACTION_DELETE,
-        SyncData::CreateLocalDelete(TabNodePool::TabIdToTag(tag, *it),
-                                    syncer::SESSIONS)));
-  }
+  AppendDeletionsForTabNodes(tab_node_ids_to_delete, tag, change_output);
   if (!sessions_updated_callback_.is_null())
     sessions_updated_callback_.Run();
 }
@@ -912,7 +929,7 @@
     const std::string& foreign_session_tag) {
   DCHECK_NE(foreign_session_tag, current_machine_tag());
   DVLOG(1) << "Disassociating session " << foreign_session_tag;
-  return session_tracker_.DeleteSession(foreign_session_tag);
+  return session_tracker_.DeleteForeignSession(foreign_session_tag);
 }
 
 bool SessionsSyncManager::GetForeignSession(
@@ -958,66 +975,41 @@
   return success;
 }
 
-void SessionsSyncManager::LocalTabDelegateToSpecifics(
-    const SyncedTabDelegate& tab_delegate,
-    sync_pb::SessionSpecifics* specifics) {
-  sessions::SessionTab* session_tab = nullptr;
-  session_tab = session_tracker_.GetTab(current_machine_tag(),
-                                        tab_delegate.GetSessionId(),
-                                        tab_delegate.GetSyncId());
-  SetSessionTabFromDelegate(tab_delegate, base::Time::Now(), session_tab);
-  SetVariationIds(session_tab);
-  sync_pb::SessionTab tab_s = session_tab->ToSyncData();
-  specifics->set_session_tag(current_machine_tag_);
-  specifics->set_tab_node_id(tab_delegate.GetSyncId());
-  specifics->mutable_tab()->CopyFrom(tab_s);
-}
-
 void SessionsSyncManager::AssociateRestoredPlaceholderTab(
     const SyncedTabDelegate& tab_delegate,
     SessionID::id_type new_tab_id,
     SessionID::id_type new_window_id,
-    const syncer::SyncDataList& restored_tabs,
     syncer::SyncChangeList* change_output) {
   DCHECK_NE(tab_delegate.GetSyncId(), TabNodePool::kInvalidTabNodeID);
-  // Rewrite the tab using |restored_tabs| to retrieve the specifics.
-  if (restored_tabs.empty()) {
-    DLOG(WARNING) << "Can't Update tab ID.";
+
+  // It's possible the placeholder tab is associated with a tab node that's
+  // since been deleted. If that's the case, there's no way to reassociate it,
+  // so just return now without adding the tab to the session tracker.
+  if (!session_tracker_.IsLocalTabNodeAssociated(tab_delegate.GetSyncId())) {
+    DVLOG(1) << "Restored placeholder tab's node " << tab_delegate.GetSyncId()
+             << " deleted.";
     return;
   }
 
-  for (syncer::SyncDataList::const_iterator it = restored_tabs.begin();
-       it != restored_tabs.end(); ++it) {
-    if (it->GetSpecifics().session().tab_node_id() !=
-        tab_delegate.GetSyncId()) {
-      continue;
-    }
+  // Update tracker with the new association (and inform it of the tab node
+  // in the process).
+  session_tracker_.ReassociateLocalTab(tab_delegate.GetSyncId(), new_tab_id);
 
-    sync_pb::EntitySpecifics entity;
-    sync_pb::SessionSpecifics* specifics = entity.mutable_session();
-    specifics->CopyFrom(it->GetSpecifics().session());
-    DCHECK(specifics->has_tab());
+  // Update the window id on the SessionTab itself.
+  sessions::SessionTab* local_tab =
+      session_tracker_.GetTab(current_machine_tag(), new_tab_id);
+  local_tab->window_id.set_id(new_window_id);
 
-    // Update tab node pool with the new association.
-    local_tab_pool_.ReassociateTabNode(tab_delegate.GetSyncId(), new_tab_id);
-    TabLink* tab_link = new TabLink(tab_delegate.GetSyncId(), &tab_delegate);
-    local_tab_map_[new_tab_id] = make_linked_ptr<TabLink>(tab_link);
-
-    if (specifics->tab().tab_id() == new_tab_id &&
-        specifics->tab().window_id() == new_window_id)
-      return;
-
-    // Either the tab_id or window_id changed (e.g due to session restore), so
-    // update the sync node.
-    specifics->mutable_tab()->set_tab_id(new_tab_id);
-    specifics->mutable_tab()->set_window_id(new_window_id);
-    syncer::SyncData data = syncer::SyncData::CreateLocalData(
-        TabNodePool::TabIdToTag(current_machine_tag_, specifics->tab_node_id()),
-        current_session_name_, entity);
-    change_output->push_back(
-        syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE, data));
-    return;
-  }
+  // Rewrite the specifics based on the reassociated SessionTab to preserve
+  // the new tab and window ids.
+  sync_pb::EntitySpecifics entity;
+  entity.mutable_session()->CopyFrom(SessionTabToSpecifics(
+      *local_tab, current_machine_tag(), tab_delegate.GetSyncId()));
+  syncer::SyncData data = syncer::SyncData::CreateLocalData(
+      TabNodeIdToTag(current_machine_tag(), tab_delegate.GetSyncId()),
+      current_session_name_, entity);
+  change_output->push_back(
+      syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE, data));
 }
 
 // static
diff --git a/components/sync_sessions/sessions_sync_manager.h b/components/sync_sessions/sessions_sync_manager.h
index 66ec40e..d685c65 100644
--- a/components/sync_sessions/sessions_sync_manager.h
+++ b/components/sync_sessions/sessions_sync_manager.h
@@ -30,7 +30,6 @@
 #include "components/sync_sessions/revisit/page_revisit_broadcaster.h"
 #include "components/sync_sessions/synced_session.h"
 #include "components/sync_sessions/synced_session_tracker.h"
-#include "components/sync_sessions/tab_node_pool.h"
 
 namespace syncer {
 class LocalDeviceInfoProvider;
@@ -118,37 +117,6 @@
   void DoGarbageCollection();
 
  private:
-  // Keep all the links to local tab data in one place. A tab_node_id and tab
-  // must be passed at creation. The tab_node_id is not mutable, although
-  // all other fields are.
-  class TabLink {
-   public:
-    TabLink(int tab_node_id, const SyncedTabDelegate* tab)
-        : tab_node_id_(tab_node_id), tab_(tab) {}
-
-    void set_tab(const SyncedTabDelegate* tab) { tab_ = tab; }
-    void set_url(const GURL& url) { url_ = url; }
-
-    int tab_node_id() const { return tab_node_id_; }
-    const SyncedTabDelegate* tab() const { return tab_; }
-    const GURL& url() const { return url_; }
-
-   private:
-    // The id for the sync node this tab is stored in.
-    const int tab_node_id_;
-
-    // The tab object itself.
-    const SyncedTabDelegate* tab_;
-
-    // The currently visible url of the tab (used for syncing favicons).
-    GURL url_;
-
-    DISALLOW_COPY_AND_ASSIGN(TabLink);
-  };
-
-  // Container for accessing local tab data by tab id.
-  typedef std::map<SessionID::id_type, linked_ptr<TabLink>> TabLinksMap;
-
   friend class extensions::ExtensionSessionsTest;
   friend class SessionsSyncManagerTest;
   FRIEND_TEST_ALL_PREFIXES(SessionsSyncManagerTest, PopulateSessionHeader);
@@ -182,20 +150,16 @@
 
   void InitializeCurrentMachineTag(const std::string& cache_guid);
 
-  // Load and add window or tab data for a foreign session to our internal
+  // Load and add window or tab data from synced specifics to our internal
   // tracking.
-  void UpdateTrackerWithForeignSession(
-      const sync_pb::SessionSpecifics& specifics,
-      const base::Time& modification_time);
+  void UpdateTrackerWithSpecifics(const sync_pb::SessionSpecifics& specifics,
+                                  const base::Time& modification_time);
 
   // Returns true if |sync_data| contained a header node for the current
-  // machine, false otherwise. |restored_tabs| is a filtered tab-only
-  // subset of |sync_data| returned by this function for convenience.
-  // |new_changes| is a link to the SyncChange pipeline that exists in the
-  // caller's context. This function will append necessary changes for
-  // processing later.
+  // machine, false otherwise. |new_changes| is a link to the SyncChange
+  // pipeline that exists in the caller's context. This function will append
+  // necessary changes for processing later.
   bool InitFromSyncModel(const syncer::SyncDataList& sync_data,
-                         syncer::SyncDataList* restored_tabs,
                          syncer::SyncChangeList* new_changes);
 
   // Helper to construct a deletion SyncChange for a *tab node*.
@@ -244,11 +208,6 @@
   // RELOAD_TABS will additionally cause a resync of all tabs (same as calling
   // AssociateTabs with a vector of all tabs).
   //
-  // |restored_tabs| is a filtered tab-only subset of initial sync data, if
-  // available (during MergeDataAndStartSyncing). It can be used to obtain
-  // baseline SessionSpecifics for tabs we can't fully associate any other
-  // way because they don't yet have a WebContents.
-  //
   // Returns: false if the local session's sync nodes were deleted and
   // reassociation is necessary, true otherwise.
   //
@@ -257,7 +216,6 @@
   // changes for processing later.
   enum ReloadTabsOption { RELOAD_TABS, DONT_RELOAD_TABS };
   void AssociateWindows(ReloadTabsOption option,
-                        const syncer::SyncDataList& restored_tabs,
                         syncer::SyncChangeList* change_output);
 
   // Loads and reassociates the local tabs referenced in |tabs|.
@@ -286,17 +244,10 @@
   // as they may have changed after a session was restored.  This method
   // compares new_tab_id and new_window_id against the previously persisted tab
   // ID and window ID (from our TabNodePool) and updates them if either differs.
-  // |restored_tabs| is a filtered tab-only subset of initial sync data, if
-  // available (during MergeDataAndStartSyncing). It can be used to obtain
-  // baseline SessionSpecifics for tabs we can't fully associate any other
-  // way because they don't yet have a WebContents.
-  // TODO(tim): Bug 98892. We should be able to test this for this on android
-  // even though we didn't have tests for old API-based sessions sync.
   void AssociateRestoredPlaceholderTab(
       const SyncedTabDelegate& tab_delegate,
       SessionID::id_type new_tab_id,
       SessionID::id_type new_window_id,
-      const syncer::SyncDataList& restored_tabs,
       syncer::SyncChangeList* change_output);
 
   // Stops and re-starts syncing to rebuild association mappings. Returns true
@@ -323,15 +274,9 @@
   // The client of this sync sessions datatype.
   SyncSessionsClient* const sessions_client_;
 
-  // Mapping of current open (local) tabs to their sync identifiers.
-  TabLinksMap local_tab_map_;
-
   SyncedSessionTracker session_tracker_;
   FaviconCache favicon_cache_;
 
-  // Pool of used/available sync nodes associated with local tabs.
-  TabNodePool local_tab_pool_;
-
   // Tracks whether our local representation of which sync nodes map to what
   // tabs (belonging to the current local session) is inconsistent.  This can
   // happen if a foreign client deems our session as "stale" and decides to
diff --git a/components/sync_sessions/synced_session_tracker.cc b/components/sync_sessions/synced_session_tracker.cc
index a74b877c..1470c7f 100644
--- a/components/sync_sessions/synced_session_tracker.cc
+++ b/components/sync_sessions/synced_session_tracker.cc
@@ -53,6 +53,8 @@
 
 void SyncedSessionTracker::SetLocalSessionTag(
     const std::string& local_session_tag) {
+  DCHECK(local_session_tag_.empty());
+  DCHECK(!local_session_tag.empty());
   local_session_tag_ = local_session_tag;
 }
 
@@ -90,6 +92,9 @@
     const std::string& tag,
     SessionID::id_type tab_id,
     const sessions::SessionTab** tab) const {
+  if (tab_id == TabNodePool::kInvalidTabID)
+    return false;
+
   DCHECK(tab);
   auto tab_map_iter = synced_tab_map_.find(tag);
   if (tab_map_iter == synced_tab_map_.end()) {
@@ -107,8 +112,9 @@
   return true;
 }
 
-void SyncedSessionTracker::LookupTabNodeIds(const std::string& session_tag,
-                                            std::set<int>* tab_node_ids) {
+void SyncedSessionTracker::LookupForeignTabNodeIds(
+    const std::string& session_tag,
+    std::set<int>* tab_node_ids) const {
   tab_node_ids->clear();
   auto session_iter = synced_session_map_.find(session_tag);
   if (session_iter != synced_session_map_.end()) {
@@ -144,7 +150,9 @@
   return synced_session_map_[session_tag].get();
 }
 
-bool SyncedSessionTracker::DeleteSession(const std::string& session_tag) {
+bool SyncedSessionTracker::DeleteForeignSession(
+    const std::string& session_tag) {
+  DCHECK_NE(local_session_tag_, session_tag);
   unmapped_windows_.erase(session_tag);
   unmapped_tabs_.erase(session_tag);
 
@@ -188,13 +196,14 @@
 
 void SyncedSessionTracker::DeleteForeignTab(const std::string& session_tag,
                                             int tab_node_id) {
+  DCHECK_NE(local_session_tag_, session_tag);
   auto session_iter = synced_session_map_.find(session_tag);
   if (session_iter != synced_session_map_.end()) {
     session_iter->second->tab_node_ids.erase(tab_node_id);
   }
 }
 
-void SyncedSessionTracker::CleanupSession(const std::string& session_tag) {
+void SyncedSessionTracker::CleanupSessionImpl(const std::string& session_tag) {
   for (const auto& window_pair : unmapped_windows_[session_tag])
     synced_window_map_[session_tag].erase(window_pair.first);
   unmapped_windows_[session_tag].clear();
@@ -233,20 +242,19 @@
 
 void SyncedSessionTracker::PutTabInWindow(const std::string& session_tag,
                                           SessionID::id_type window_id,
-                                          SessionID::id_type tab_id,
-                                          size_t tab_index) {
+                                          SessionID::id_type tab_id) {
   // We're called here for two reasons. 1) We've received an update to the
-  // SessionWindow information of a SessionHeader node for a foreign session,
+  // SessionWindow information of a SessionHeader node for a session,
   // and 2) The SessionHeader node for our local session changed. In both cases
   // we need to update our tracking state to reflect the change.
   //
   // Because the SessionHeader nodes are separate from the individual tab nodes
   // and we don't store tab_node_ids in the header / SessionWindow specifics,
-  // the tab_node_ids are not always available when processing headers.
-  // We know that we will eventually process (via GetTab) every single tab node
-  // in the system, so we permit ourselves to use kInvalidTabNodeID here and
-  // rely on the later update to build the mapping (or a restart).
-  GetTabImpl(session_tag, tab_id, TabNodePool::kInvalidTabNodeID);
+  // the tab_node_ids are not always available when processing headers. We know
+  // that we will eventually process (via GetTab) every single tab node in the
+  // system, so we permit ourselves to just call GetTab and ignore the result,
+  // creating a placeholder SessionTab in the process.
+  GetTab(session_tag, tab_id);
 
   // The tab should be unmapped.
   std::unique_ptr<sessions::SessionTab> tab;
@@ -255,60 +263,30 @@
     tab = std::move(it->second);
     unmapped_tabs_[session_tag].erase(it);
   }
-  DCHECK(tab);
+  CHECK(tab) << "crbug.com/673618 Attempting to map tab " << tab_id
+             << " multiple times!";
 
   tab->window_id.set_id(window_id);
   DVLOG(1) << "  - tab " << tab_id << " added to window " << window_id;
   DCHECK(GetSession(session_tag)->windows.find(window_id) !=
          GetSession(session_tag)->windows.end());
   auto& window_tabs = GetSession(session_tag)->windows[window_id]->tabs;
-  if (window_tabs.size() <= tab_index) {
-    window_tabs.resize(tab_index + 1);
-  }
-  DCHECK(!window_tabs[tab_index]);
-  window_tabs[tab_index] = std::move(tab);
+  window_tabs.push_back(std::move(tab));
+}
+
+void SyncedSessionTracker::OnTabNodeSeen(const std::string& session_tag,
+                                         int tab_node_id) {
+  GetSession(session_tag)->tab_node_ids.insert(tab_node_id);
 }
 
 sessions::SessionTab* SyncedSessionTracker::GetTab(
     const std::string& session_tag,
-    SessionID::id_type tab_id,
-    int tab_node_id) {
-  DCHECK_NE(TabNodePool::kInvalidTabNodeID, tab_node_id);
-  return GetTabImpl(session_tag, tab_id, tab_node_id);
-}
-
-sessions::SessionTab* SyncedSessionTracker::GetTabImpl(
-    const std::string& session_tag,
-    SessionID::id_type tab_id,
-    int tab_node_id) {
+    SessionID::id_type tab_id) {
+  CHECK_NE(TabNodePool::kInvalidTabNodeID, tab_id) << "crbug.com/673618";
   sessions::SessionTab* tab_ptr = nullptr;
   auto iter = synced_tab_map_[session_tag].find(tab_id);
   if (iter != synced_tab_map_[session_tag].end()) {
     tab_ptr = iter->second;
-    if (tab_node_id != TabNodePool::kInvalidTabNodeID &&
-        tab_id != TabNodePool::kInvalidTabID) {
-      // TabIDs are not stable across restarts of a client. Consider this
-      // example with two tabs:
-      //
-      // http://a.com  TabID1 --> NodeIDA
-      // http://b.com  TabID2 --> NodeIDB
-      //
-      // After restart, tab ids are reallocated. e.g, one possibility:
-      // http://a.com TabID2 --> NodeIDA
-      // http://b.com TabID1 --> NodeIDB
-      //
-      // If that happend on a remote client, here we will see an update to
-      // TabID1 with tab_node_id changing from NodeIDA to NodeIDB, and TabID2
-      // with tab_node_id changing from NodeIDB to NodeIDA.
-      //
-      // We can also wind up here if we created this tab as an out-of-order
-      // update to the header node for this session before actually associating
-      // the tab itself, so the tab node id wasn't available at the time and
-      // is currently kInvalidTabNodeID.
-      //
-      // In both cases, we can safely throw it into the set of node ids.
-      GetSession(session_tag)->tab_node_ids.insert(tab_node_id);
-    }
 
     if (VLOG_IS_ON(1)) {
       std::string title;
@@ -328,7 +306,6 @@
     tab->tab_id.set_id(tab_id);
     synced_tab_map_[session_tag][tab_id] = tab_ptr;
     unmapped_tabs_[session_tag][tab_id] = std::move(tab);
-    GetSession(session_tag)->tab_node_ids.insert(tab_node_id);
     DVLOG(1) << "Getting "
              << (session_tag == local_session_tag_ ? "local session"
                                                    : session_tag)
@@ -339,6 +316,99 @@
   return tab_ptr;
 }
 
+void SyncedSessionTracker::CleanupForeignSession(
+    const std::string& session_tag) {
+  DCHECK_NE(local_session_tag_, session_tag);
+  CleanupSessionImpl(session_tag);
+}
+
+void SyncedSessionTracker::CleanupLocalTabs(std::set<int>* deleted_node_ids) {
+  DCHECK(!local_session_tag_.empty());
+  for (const auto& tab_pair : unmapped_tabs_[local_session_tag_])
+    local_tab_pool_.FreeTab(tab_pair.first);
+  CleanupSessionImpl(local_session_tag_);
+  local_tab_pool_.CleanupTabNodes(deleted_node_ids);
+  for (int tab_node_id : *deleted_node_ids) {
+    GetSession(local_session_tag_)->tab_node_ids.erase(tab_node_id);
+  }
+}
+
+bool SyncedSessionTracker::GetTabNodeFromLocalTabId(SessionID::id_type tab_id,
+                                                    int* tab_node_id) {
+  DCHECK(!local_session_tag_.empty());
+  // Ensure a placeholder SessionTab is in place, if not already.
+  // Although we don't need a SessionTab to fulfill this request, this forces
+  // the
+  // creation of one if it doesn't already exist. This helps to make sure we're
+  // tracking this |tab_id| if |local_tab_pool_| is, and everyone's data
+  // structures
+  // are kept in sync and as consistent as possible.
+  GetTab(local_session_tag_, tab_id);  // Ignore result.
+
+  bool reused_existing_tab =
+      local_tab_pool_.GetTabNodeForTab(tab_id, tab_node_id);
+  DCHECK_NE(TabNodePool::kInvalidTabNodeID, *tab_node_id);
+  GetSession(local_session_tag_)->tab_node_ids.insert(*tab_node_id);
+  return reused_existing_tab;
+}
+
+bool SyncedSessionTracker::IsLocalTabNodeAssociated(int tab_node_id) {
+  if (tab_node_id == TabNodePool::kInvalidTabNodeID)
+    return false;
+  return local_tab_pool_.GetTabIdFromTabNodeId(tab_node_id) !=
+         TabNodePool::kInvalidTabID;
+}
+
+void SyncedSessionTracker::ReassociateLocalTab(int tab_node_id,
+                                               SessionID::id_type new_tab_id) {
+  DCHECK(!local_session_tag_.empty());
+  DCHECK_NE(TabNodePool::kInvalidTabNodeID, tab_node_id);
+  DCHECK_NE(TabNodePool::kInvalidTabID, new_tab_id);
+
+  SessionID::id_type old_tab_id =
+      local_tab_pool_.GetTabIdFromTabNodeId(tab_node_id);
+  local_tab_pool_.ReassociateTabNode(tab_node_id, new_tab_id);
+
+  sessions::SessionTab* tab_ptr = nullptr;
+
+  auto old_tab_iter = synced_tab_map_[local_session_tag_].find(old_tab_id);
+  if (old_tab_id != TabNodePool::kInvalidTabID &&
+      old_tab_iter != synced_tab_map_[local_session_tag_].end()) {
+    tab_ptr = old_tab_iter->second;
+    // Remove the tab from the synced tab map under the old id.
+    synced_tab_map_[local_session_tag_].erase(old_tab_iter);
+  } else {
+    // It's possible a placeholder is already in place for the new tab. If so,
+    // reuse it, otherwise create a new one (which will default to unmapped).
+    tab_ptr = GetTab(local_session_tag_, new_tab_id);
+  }
+
+  // If the old tab is unmapped, update the tab id under which it is indexed.
+  auto unmapped_tabs_iter = unmapped_tabs_[local_session_tag_].find(old_tab_id);
+  if (old_tab_id != TabNodePool::kInvalidTabID &&
+      unmapped_tabs_iter != unmapped_tabs_[local_session_tag_].end()) {
+    std::unique_ptr<sessions::SessionTab> tab =
+        std::move(unmapped_tabs_iter->second);
+    DCHECK_EQ(tab_ptr, tab.get());
+    unmapped_tabs_[local_session_tag_].erase(unmapped_tabs_iter);
+    unmapped_tabs_[local_session_tag_][new_tab_id] = std::move(tab);
+  }
+
+  // Update the tab id.
+  if (old_tab_id != TabNodePool::kInvalidTabID) {
+    DVLOG(1) << "Remapped tab " << old_tab_id << " with node " << tab_node_id
+             << " to tab " << new_tab_id;
+  } else {
+    DVLOG(1) << "Mapped new tab node " << tab_node_id << " to tab "
+             << new_tab_id;
+  }
+  tab_ptr->tab_id.set_id(new_tab_id);
+
+  // Add the tab back into the tab map with the new id.
+  synced_tab_map_[local_session_tag_][new_tab_id] = tab_ptr;
+  GetSession(local_session_tag_)->tab_node_ids.insert(tab_node_id);
+}
+
 void SyncedSessionTracker::Clear() {
   // Cleanup unmapped tabs and windows.
   unmapped_windows_.clear();
@@ -352,6 +422,7 @@
   synced_window_map_.clear();
   synced_tab_map_.clear();
 
+  local_tab_pool_.Clear();
   local_session_tag_.clear();
 }
 
diff --git a/components/sync_sessions/synced_session_tracker.h b/components/sync_sessions/synced_session_tracker.h
index 35123d7..05fbac7 100644
--- a/components/sync_sessions/synced_session_tracker.h
+++ b/components/sync_sessions/synced_session_tracker.h
@@ -40,8 +40,7 @@
   explicit SyncedSessionTracker(SyncSessionsClient* sessions_client);
   ~SyncedSessionTracker();
 
-  // We track and distinguish the local session from foreign sessions.
-  void SetLocalSessionTag(const std::string& local_session_tag);
+  // **** Synced session/tab query methods. ****
 
   // Fill a preallocated vector with all foreign sessions we're tracking (skips
   // the local session object). SyncedSession ownership remains within the
@@ -51,6 +50,11 @@
   bool LookupAllForeignSessions(std::vector<const SyncedSession*>* sessions,
                                 SessionLookup lookup) const;
 
+  // Fills |tab_node_ids| with the tab node ids (see GetTab) for all the tabs*
+  // associated with the session having tag |session_tag|.
+  void LookupForeignTabNodeIds(const std::string& session_tag,
+                               std::set<int>* tab_node_ids) const;
+
   // Attempts to look up the session windows associatd with the session given
   // by |session_tag|. Ownership of SessionWindows stays within the
   // SyncedSessionTracker.
@@ -76,15 +80,13 @@
   // this won't create-if-not-present.
   bool LookupLocalSession(const SyncedSession** output) const;
 
+  // **** Methods for manipulating synced sessions and tabs. ****
+
   // Returns a pointer to the SyncedSession object associated with
   // |session_tag|. If none exists, creates one. Ownership of the
   // SyncedSession remains within the SyncedSessionTracker.
   SyncedSession* GetSession(const std::string& session_tag);
 
-  // Deletes the session associated with |session_tag| if it exists.
-  // Returns true if the session existed and was deleted, false otherwise.
-  bool DeleteSession(const std::string& session_tag);
-
   // Resets the tracking information for the session specified by |session_tag|.
   // This involves clearing all the windows and tabs from the session, while
   // keeping pointers saved in the synced_window_map_ and synced_tab_map_. Once
@@ -94,19 +96,6 @@
   // tabs not owned.
   void ResetSessionTracking(const std::string& session_tag);
 
-  // Tracks the deletion of a foreign tab by removing the given |tab_node_id|
-  // from the parent session. Doesn't actually remove any tab objects because
-  // the header may have or may not have already been updated to no longer
-  // parent this tab. Regardless, when the header is updated then cleanup will
-  // remove the actual tab data. However, this method always needs to be called
-  // upon foreign tab deletion, otherwise LookupTabNodeIds(...) may return
-  // already deleted tab node ids.
-  void DeleteForeignTab(const std::string& session_tag, int tab_node_id);
-
-  // Deletes those windows and tabs associated with |session_tag| that are no
-  // longer owned. See ResetSessionTracking(...).
-  void CleanupSession(const std::string& session_tag);
-
   // Adds the window with id |window_id| to the session specified by
   // |session_tag|. If none existed for that session, creates one. Similarly, if
   // the session did not exist yet, creates it. Ownership of the SessionWindow
@@ -122,21 +111,71 @@
   // ensure we having mapping information for this session.
   void PutTabInWindow(const std::string& session_tag,
                       SessionID::id_type window_id,
-                      SessionID::id_type tab_id,
-                      size_t tab_index);
+                      SessionID::id_type tab_id);
 
-  // Returns a pointer to the SessionTab object associated with |tab_id| for
-  // the session specified with |session_tag|. If none exists, creates one.
-  // Ownership of the SessionTab remains within the SyncedSessionTracker.
-  // |tab_node_id| must be a valid node id for the node backing this tab.
+  // Adds |tab_node_id| to the session specified by |session_tag|, creating that
+  // session if necessary. This is necessary to ensure that each session has an
+  // up to date list of tab nodes linked to it for session deletion purposes.
+  // Note that this won't update the local tab pool, even if the local session
+  // tag is passed. The tab pool is only updated with new tab nodes when they're
+  // associated with a tab id (see ReassociateLocalTabNode or
+  // GetTabNodeFromLocalTabId).
+  void OnTabNodeSeen(const std::string& session_tag, int tab_node_id);
+
+  // Returns a pointer to the SessionTab object associated with
+  // |tab_id| for the session specified with |session_tag|.
+  // Note: Ownership of the SessionTab remains within the SyncedSessionTracker.
+  // TODO(zea): Replace SessionTab with a Sync specific wrapper.
+  // crbug.com/662597
   sessions::SessionTab* GetTab(const std::string& session_tag,
-                               SessionID::id_type tab_id,
-                               int tab_node_id);
+                               SessionID::id_type tab_id);
 
-  // Fills |tab_node_ids| with the tab node ids (see GetTab) for all the tabs*
-  // associated with the session having tag |session_tag|.
-  void LookupTabNodeIds(const std::string& session_tag,
-                        std::set<int>* tab_node_ids);
+  // **** Methods specific to foreign sessions. ****
+
+  // Tracks the deletion of a foreign tab by removing the given |tab_node_id|
+  // from the parent session. Doesn't actually remove any tab objects because
+  // the header may have or may not have already been updated to no longer
+  // parent this tab. Regardless, when the header is updated then cleanup will
+  // remove the actual tab data. However, this method always needs to be called
+  // upon foreign tab deletion, otherwise LookupTabNodeIds(...) may return
+  // already deleted tab node ids.
+  void DeleteForeignTab(const std::string& session_tag, int tab_node_id);
+
+  // Deletes the session associated with |session_tag| if it exists.
+  // Returns true if the session existed and was deleted, false otherwise.
+  bool DeleteForeignSession(const std::string& session_tag);
+
+  // Deletes those windows and tabs associated with |session_tag| that are no
+  // longer owned. See ResetSessionTracking(...)..
+  void CleanupForeignSession(const std::string& session_tag);
+
+  // **** Methods specific to the local session. ****
+
+  // Set the local session tag. Must be called before any other local session
+  // methods are invoked.
+  void SetLocalSessionTag(const std::string& local_session_tag);
+
+  // Similar to CleanupForeignSession, but also marks any unmapped tabs as free
+  // in the tab node pool and fills |deleted_node_ids| with the set of locally
+  // free tab nodes to be deleted.
+  void CleanupLocalTabs(std::set<int>* deleted_node_ids);
+
+  // Fills |tab_node_id| with a tab node for |tab_id|. Returns true if an
+  // existing tab node was found, false if there was none and one had to be
+  // created.
+  bool GetTabNodeFromLocalTabId(SessionID::id_type tab_id, int* tab_node_id);
+
+  // Returns whether |tab_node_id| refers to a valid tab node that is associated
+  // with a tab.
+  bool IsLocalTabNodeAssociated(int tab_node_id);
+
+  // Reassociates the tab denoted by |tab_node_id| with a new tab id, preserving
+  // any previous SessionTab object the node was associated with. This is useful
+  // on restart when sync needs to reassociate tabs from a previous session with
+  // newly restored tabs (and can be used in conjunction with PutTabInWindow).
+  void ReassociateLocalTab(int tab_node_id, SessionID::id_type new_tab_id);
+
+  // **** Methods for querying/manipulating overall state ****.
 
   // Free the memory for all dynamically allocated objects and clear the
   // tracking structures.
@@ -160,20 +199,21 @@
   }
 
  private:
-  // Implementation for GetTab(...) above, permits invalid tab_node_id.
-  sessions::SessionTab* GetTabImpl(const std::string& session_tag,
-                                   SessionID::id_type tab_id,
-                                   int tab_node_id);
+  friend class SessionsSyncManagerTest;
+  friend class SyncedSessionTrackerTest;
+
+  // Implementation of CleanupForeignSession/CleanupLocalTabs.
+  void CleanupSessionImpl(const std::string& session_tag);
 
   // The client of the sync sessions datatype.
   SyncSessionsClient* const sessions_client_;
 
-  // The mapping of tab/window ids to their SessionTab/SessionWindow objects.
+  // The mapping of tab/window to their SessionTab/SessionWindow objects.
   // The SessionTab/SessionWindow objects referred to may be owned either by the
   // session in the |synced_session_map_| or be temporarily unmapped and live in
   // the |unmapped_tabs_|/|unmapped_windows_| collections.
   //
-  // Map: session tag -> (tab/window id -> SessionTab*/SessionWindow*)
+  // Map: session tag -> (tab/window -> SessionTab*/SessionWindow*)
   std::map<std::string, std::map<SessionID::id_type, sessions::SessionTab*>>
       synced_tab_map_;
   std::map<std::string, std::map<SessionID::id_type, sessions::SessionWindow*>>
@@ -203,6 +243,9 @@
   // sessions.
   std::string local_session_tag_;
 
+  // Pool of used/available sync nodes associated with local tabs.
+  TabNodePool local_tab_pool_;
+
   DISALLOW_COPY_AND_ASSIGN(SyncedSessionTracker);
 };
 
diff --git a/components/sync_sessions/synced_session_tracker_unittest.cc b/components/sync_sessions/synced_session_tracker_unittest.cc
index 68c1f471..a48cf67 100644
--- a/components/sync_sessions/synced_session_tracker_unittest.cc
+++ b/components/sync_sessions/synced_session_tracker_unittest.cc
@@ -17,6 +17,15 @@
 
 const char kValidUrl[] = "http://www.example.com";
 const char kInvalidUrl[] = "invalid.url";
+const char kTag[] = "tag";
+const char kTag2[] = "tag2";
+const char kTag3[] = "tag3";
+const char kTitle[] = "title";
+const int kWindow1 = 1;
+const int kTabNode = 0;
+const int kTab1 = 15;
+const int kTab2 = 25;
+const int kTab3 = 35;
 
 }  // namespace
 
@@ -26,6 +35,7 @@
   ~SyncedSessionTrackerTest() override {}
 
   SyncedSessionTracker* GetTracker() { return &tracker_; }
+  TabNodePool* GetTabNodePool() { return &tracker_.local_tab_pool_; }
 
  private:
   FakeSyncSessionsClient sessions_client_;
@@ -33,34 +43,33 @@
 };
 
 TEST_F(SyncedSessionTrackerTest, GetSession) {
-  SyncedSession* session1 = GetTracker()->GetSession("tag");
-  SyncedSession* session2 = GetTracker()->GetSession("tag2");
-  ASSERT_EQ(session1, GetTracker()->GetSession("tag"));
+  SyncedSession* session1 = GetTracker()->GetSession(kTag);
+  SyncedSession* session2 = GetTracker()->GetSession(kTag2);
+  ASSERT_EQ(session1, GetTracker()->GetSession(kTag));
   ASSERT_NE(session1, session2);
   // Should clean up memory on its own.
 }
 
 TEST_F(SyncedSessionTrackerTest, GetTabUnmapped) {
-  sessions::SessionTab* tab = GetTracker()->GetTab("tag", 0, 0);
-  ASSERT_EQ(tab, GetTracker()->GetTab("tag", 0, 0));
+  sessions::SessionTab* tab = GetTracker()->GetTab(kTag, 0);
+  ASSERT_EQ(tab, GetTracker()->GetTab(kTag, 0));
   // Should clean up memory on its own.
 }
 
 TEST_F(SyncedSessionTrackerTest, PutWindowInSession) {
-  GetTracker()->PutWindowInSession("tag", 0);
-  SyncedSession* session = GetTracker()->GetSession("tag");
+  GetTracker()->PutWindowInSession(kTag, 0);
+  SyncedSession* session = GetTracker()->GetSession(kTag);
   ASSERT_EQ(1U, session->windows.size());
   // Should clean up memory on its own.
 }
 
 TEST_F(SyncedSessionTrackerTest, PutTabInWindow) {
-  GetTracker()->PutWindowInSession("tag", 10);
-  GetTracker()->PutTabInWindow("tag", 10, 15,
-                               0);  // win id 10, tab id 15, tab ind 0.
-  SyncedSession* session = GetTracker()->GetSession("tag");
+  GetTracker()->PutWindowInSession(kTag, 10);
+  GetTracker()->PutTabInWindow(kTag, 10, 15);  // win id 10, tab id 15
+  SyncedSession* session = GetTracker()->GetSession(kTag);
   ASSERT_EQ(1U, session->windows.size());
   ASSERT_EQ(1U, session->windows[10]->tabs.size());
-  ASSERT_EQ(GetTracker()->GetTab("tag", 15, 1),
+  ASSERT_EQ(GetTracker()->GetTab(kTag, 15),
             session->windows[10]->tabs[0].get());
   // Should clean up memory on its own.
 }
@@ -69,28 +78,28 @@
   std::vector<const SyncedSession*> sessions;
   ASSERT_FALSE(GetTracker()->LookupAllForeignSessions(
       &sessions, SyncedSessionTracker::PRESENTABLE));
-  GetTracker()->GetSession("tag1");
-  GetTracker()->PutWindowInSession("tag1", 0);
-  GetTracker()->PutTabInWindow("tag1", 0, 15, 0);
-  sessions::SessionTab* tab = GetTracker()->GetTab("tag1", 15, 1);
+  GetTracker()->GetSession(kTag);
+  GetTracker()->PutWindowInSession(kTag, 0);
+  GetTracker()->PutTabInWindow(kTag, 0, 15);
+  sessions::SessionTab* tab = GetTracker()->GetTab(kTag, 15);
   ASSERT_TRUE(tab);
   tab->navigations.push_back(
       sessions::SerializedNavigationEntryTestHelper::CreateNavigation(kValidUrl,
-                                                                      "title"));
-  GetTracker()->GetSession("tag2");
-  GetTracker()->GetSession("tag3");
-  GetTracker()->PutWindowInSession("tag3", 0);
-  GetTracker()->PutTabInWindow("tag3", 0, 15, 0);
-  tab = GetTracker()->GetTab("tag3", 15, 1);
+                                                                      kTitle));
+  GetTracker()->GetSession(kTag2);
+  GetTracker()->GetSession(kTag3);
+  GetTracker()->PutWindowInSession(kTag3, 0);
+  GetTracker()->PutTabInWindow(kTag3, 0, 15);
+  tab = GetTracker()->GetTab(kTag3, 15);
   ASSERT_TRUE(tab);
   tab->navigations.push_back(
       sessions::SerializedNavigationEntryTestHelper::CreateNavigation(
-          kInvalidUrl, "title"));
+          kInvalidUrl, kTitle));
   ASSERT_TRUE(GetTracker()->LookupAllForeignSessions(
       &sessions, SyncedSessionTracker::PRESENTABLE));
   // Only the session with a valid window and tab gets returned.
   ASSERT_EQ(1U, sessions.size());
-  ASSERT_EQ("tag1", sessions[0]->session_tag);
+  ASSERT_EQ(kTag, sessions[0]->session_tag);
 
   ASSERT_TRUE(GetTracker()->LookupAllForeignSessions(
       &sessions, SyncedSessionTracker::RAW));
@@ -99,15 +108,15 @@
 
 TEST_F(SyncedSessionTrackerTest, LookupSessionWindows) {
   std::vector<const sessions::SessionWindow*> windows;
-  ASSERT_FALSE(GetTracker()->LookupSessionWindows("tag1", &windows));
-  GetTracker()->GetSession("tag1");
-  GetTracker()->PutWindowInSession("tag1", 0);
-  GetTracker()->PutWindowInSession("tag1", 2);
-  GetTracker()->GetSession("tag2");
-  GetTracker()->PutWindowInSession("tag2", 0);
-  GetTracker()->PutWindowInSession("tag2", 2);
-  ASSERT_TRUE(GetTracker()->LookupSessionWindows("tag1", &windows));
-  ASSERT_EQ(2U, windows.size());  // Only windows from tag1 session.
+  ASSERT_FALSE(GetTracker()->LookupSessionWindows(kTag, &windows));
+  GetTracker()->GetSession(kTag);
+  GetTracker()->PutWindowInSession(kTag, 0);
+  GetTracker()->PutWindowInSession(kTag, 2);
+  GetTracker()->GetSession(kTag2);
+  GetTracker()->PutWindowInSession(kTag2, 0);
+  GetTracker()->PutWindowInSession(kTag2, 2);
+  ASSERT_TRUE(GetTracker()->LookupSessionWindows(kTag, &windows));
+  ASSERT_EQ(2U, windows.size());  // Only windows from kTag session.
   ASSERT_NE((sessions::SessionWindow*)nullptr, windows[0]);
   ASSERT_NE((sessions::SessionWindow*)nullptr, windows[1]);
   ASSERT_NE(windows[1], windows[0]);
@@ -115,40 +124,39 @@
 
 TEST_F(SyncedSessionTrackerTest, LookupSessionTab) {
   const sessions::SessionTab* tab;
-  ASSERT_FALSE(GetTracker()->LookupSessionTab("tag1", 5, &tab));
-  GetTracker()->GetSession("tag1");
-  GetTracker()->PutWindowInSession("tag1", 0);
-  GetTracker()->PutTabInWindow("tag1", 0, 5, 0);
-  ASSERT_TRUE(GetTracker()->LookupSessionTab("tag1", 5, &tab));
+  ASSERT_FALSE(
+      GetTracker()->LookupSessionTab(kTag, TabNodePool::kInvalidTabID, &tab));
+  ASSERT_FALSE(GetTracker()->LookupSessionTab(kTag, 5, &tab));
+  GetTracker()->GetSession(kTag);
+  GetTracker()->PutWindowInSession(kTag, 0);
+  GetTracker()->PutTabInWindow(kTag, 0, 5);
+  ASSERT_TRUE(GetTracker()->LookupSessionTab(kTag, 5, &tab));
   ASSERT_NE((sessions::SessionTab*)nullptr, tab);
 }
 
 TEST_F(SyncedSessionTrackerTest, Complex) {
-  const std::string tag1 = "tag";
-  const std::string tag2 = "tag2";
-  const std::string tag3 = "tag3";
   std::vector<sessions::SessionTab *> tabs1, tabs2;
   sessions::SessionTab* temp_tab;
   ASSERT_TRUE(GetTracker()->Empty());
   ASSERT_EQ(0U, GetTracker()->num_synced_sessions());
-  ASSERT_EQ(0U, GetTracker()->num_synced_tabs(tag1));
-  tabs1.push_back(GetTracker()->GetTab(tag1, 0, 0));
-  tabs1.push_back(GetTracker()->GetTab(tag1, 1, 1));
-  tabs1.push_back(GetTracker()->GetTab(tag1, 2, 2));
-  ASSERT_EQ(3U, GetTracker()->num_synced_tabs(tag1));
-  ASSERT_EQ(1U, GetTracker()->num_synced_sessions());
-  temp_tab = GetTracker()->GetTab(tag1, 0, 0);  // Already created.
-  ASSERT_EQ(3U, GetTracker()->num_synced_tabs(tag1));
-  ASSERT_EQ(1U, GetTracker()->num_synced_sessions());
+  ASSERT_EQ(0U, GetTracker()->num_synced_tabs(kTag));
+  tabs1.push_back(GetTracker()->GetTab(kTag, 0));
+  tabs1.push_back(GetTracker()->GetTab(kTag, 1));
+  tabs1.push_back(GetTracker()->GetTab(kTag, 2));
+  ASSERT_EQ(3U, GetTracker()->num_synced_tabs(kTag));
+  ASSERT_EQ(0U, GetTracker()->num_synced_sessions());
+  temp_tab = GetTracker()->GetTab(kTag, 0);  // Already created.
+  ASSERT_EQ(3U, GetTracker()->num_synced_tabs(kTag));
+  ASSERT_EQ(0U, GetTracker()->num_synced_sessions());
   ASSERT_EQ(tabs1[0], temp_tab);
-  tabs2.push_back(GetTracker()->GetTab(tag2, 0, 0));
-  ASSERT_EQ(1U, GetTracker()->num_synced_tabs(tag2));
-  ASSERT_EQ(2U, GetTracker()->num_synced_sessions());
-  ASSERT_FALSE(GetTracker()->DeleteSession(tag3));
+  tabs2.push_back(GetTracker()->GetTab(kTag2, 0));
+  ASSERT_EQ(1U, GetTracker()->num_synced_tabs(kTag2));
+  ASSERT_EQ(0U, GetTracker()->num_synced_sessions());
+  ASSERT_FALSE(GetTracker()->DeleteForeignSession(kTag3));
 
-  SyncedSession* session = GetTracker()->GetSession(tag1);
-  SyncedSession* session2 = GetTracker()->GetSession(tag2);
-  SyncedSession* session3 = GetTracker()->GetSession(tag3);
+  SyncedSession* session = GetTracker()->GetSession(kTag);
+  SyncedSession* session2 = GetTracker()->GetSession(kTag2);
+  SyncedSession* session3 = GetTracker()->GetSession(kTag3);
   session3->device_type = SyncedSession::TYPE_OTHER;
   ASSERT_EQ(3U, GetTracker()->num_synced_sessions());
 
@@ -157,25 +165,25 @@
   ASSERT_TRUE(session3);
   ASSERT_NE(session, session2);
   ASSERT_NE(session2, session3);
-  ASSERT_TRUE(GetTracker()->DeleteSession(tag3));
+  ASSERT_TRUE(GetTracker()->DeleteForeignSession(kTag3));
   ASSERT_EQ(2U, GetTracker()->num_synced_sessions());
 
-  GetTracker()->PutWindowInSession(tag1, 0);           // Create a window.
-  GetTracker()->PutTabInWindow(tag1, 0, 2, 0);         // No longer unmapped.
-  ASSERT_EQ(3U, GetTracker()->num_synced_tabs(tag1));  // Has not changed.
+  GetTracker()->PutWindowInSession(kTag, 0);           // Create a window.
+  GetTracker()->PutTabInWindow(kTag, 0, 2);            // No longer unmapped.
+  ASSERT_EQ(3U, GetTracker()->num_synced_tabs(kTag));  // Has not changed.
 
   const sessions::SessionTab* tab_ptr;
-  ASSERT_TRUE(GetTracker()->LookupSessionTab(tag1, 0, &tab_ptr));
+  ASSERT_TRUE(GetTracker()->LookupSessionTab(kTag, 0, &tab_ptr));
   ASSERT_EQ(tab_ptr, tabs1[0]);
-  ASSERT_TRUE(GetTracker()->LookupSessionTab(tag1, 2, &tab_ptr));
+  ASSERT_TRUE(GetTracker()->LookupSessionTab(kTag, 2, &tab_ptr));
   ASSERT_EQ(tab_ptr, tabs1[2]);
-  ASSERT_FALSE(GetTracker()->LookupSessionTab(tag1, 3, &tab_ptr));
+  ASSERT_FALSE(GetTracker()->LookupSessionTab(kTag, 3, &tab_ptr));
   ASSERT_FALSE(tab_ptr);
 
   std::vector<const sessions::SessionWindow*> windows;
-  ASSERT_TRUE(GetTracker()->LookupSessionWindows(tag1, &windows));
+  ASSERT_TRUE(GetTracker()->LookupSessionWindows(kTag, &windows));
   ASSERT_EQ(1U, windows.size());
-  ASSERT_TRUE(GetTracker()->LookupSessionWindows(tag2, &windows));
+  ASSERT_TRUE(GetTracker()->LookupSessionWindows(kTag2, &windows));
   ASSERT_EQ(0U, windows.size());
 
   // The sessions don't have valid tabs, lookup should not succeed.
@@ -187,8 +195,8 @@
   ASSERT_EQ(2U, sessions.size());
 
   GetTracker()->Clear();
-  ASSERT_EQ(0U, GetTracker()->num_synced_tabs(tag1));
-  ASSERT_EQ(0U, GetTracker()->num_synced_tabs(tag2));
+  ASSERT_EQ(0U, GetTracker()->num_synced_tabs(kTag));
+  ASSERT_EQ(0U, GetTracker()->num_synced_tabs(kTag2));
   ASSERT_EQ(0U, GetTracker()->num_synced_sessions());
 }
 
@@ -203,107 +211,101 @@
       // More attempts than tabs means we'll sometimes get the same tabs,
       // sometimes have to allocate new tabs.
       int rand_tab_num = base::RandInt(0, kMaxTabs);
-      sessions::SessionTab* tab =
-          GetTracker()->GetTab(tag, rand_tab_num, rand_tab_num + 1);
+      sessions::SessionTab* tab = GetTracker()->GetTab(tag, rand_tab_num + 1);
       ASSERT_TRUE(tab);
     }
   }
 }
 
-TEST_F(SyncedSessionTrackerTest, LookupTabNodeIds) {
+TEST_F(SyncedSessionTrackerTest, LookupForeignTabNodeIds) {
   std::set<int> result;
-  std::string tag1 = "session1";
-  std::string tag2 = "session2";
-  std::string tag3 = "session3";
 
-  GetTracker()->GetTab(tag1, 1, 1);
-  GetTracker()->GetTab(tag1, 2, 2);
-  GetTracker()->LookupTabNodeIds(tag1, &result);
+  GetTracker()->OnTabNodeSeen(kTag, 1);
+  GetTracker()->OnTabNodeSeen(kTag, 2);
+  GetTracker()->LookupForeignTabNodeIds(kTag, &result);
   EXPECT_EQ(2U, result.size());
   EXPECT_FALSE(result.end() == result.find(1));
   EXPECT_FALSE(result.end() == result.find(2));
-  GetTracker()->LookupTabNodeIds(tag2, &result);
+  GetTracker()->LookupForeignTabNodeIds(kTag2, &result);
   EXPECT_TRUE(result.empty());
 
-  GetTracker()->PutWindowInSession(tag1, 0);
-  GetTracker()->PutTabInWindow(tag1, 0, 3, 0);
-  GetTracker()->LookupTabNodeIds(tag1, &result);
+  GetTracker()->PutWindowInSession(kTag, 0);
+  GetTracker()->PutTabInWindow(kTag, 0, 3);
+  GetTracker()->LookupForeignTabNodeIds(kTag, &result);
   EXPECT_EQ(2U, result.size());
 
-  GetTracker()->GetTab(tag1, 3, 3);
-  GetTracker()->LookupTabNodeIds(tag1, &result);
+  GetTracker()->OnTabNodeSeen(kTag, 3);
+  GetTracker()->LookupForeignTabNodeIds(kTag, &result);
   EXPECT_EQ(3U, result.size());
   EXPECT_FALSE(result.end() == result.find(3));
 
-  GetTracker()->GetTab(tag2, 1, 21);
-  GetTracker()->GetTab(tag2, 2, 22);
-  GetTracker()->LookupTabNodeIds(tag2, &result);
+  GetTracker()->OnTabNodeSeen(kTag2, 21);
+  GetTracker()->OnTabNodeSeen(kTag2, 22);
+  GetTracker()->LookupForeignTabNodeIds(kTag2, &result);
   EXPECT_EQ(2U, result.size());
   EXPECT_FALSE(result.end() == result.find(21));
   EXPECT_FALSE(result.end() == result.find(22));
-  GetTracker()->LookupTabNodeIds(tag1, &result);
+  GetTracker()->LookupForeignTabNodeIds(kTag, &result);
   EXPECT_EQ(3U, result.size());
   EXPECT_FALSE(result.end() == result.find(1));
   EXPECT_FALSE(result.end() == result.find(2));
 
-  GetTracker()->LookupTabNodeIds(tag3, &result);
+  GetTracker()->LookupForeignTabNodeIds(kTag3, &result);
   EXPECT_TRUE(result.empty());
-  GetTracker()->PutWindowInSession(tag3, 1);
-  GetTracker()->PutTabInWindow(tag3, 1, 5, 0);
-  GetTracker()->LookupTabNodeIds(tag3, &result);
+  GetTracker()->PutWindowInSession(kTag3, 1);
+  GetTracker()->PutTabInWindow(kTag3, 1, 5);
+  GetTracker()->LookupForeignTabNodeIds(kTag3, &result);
   EXPECT_TRUE(result.empty());
-  EXPECT_FALSE(GetTracker()->DeleteSession(tag3));
-  GetTracker()->LookupTabNodeIds(tag3, &result);
+  EXPECT_FALSE(GetTracker()->DeleteForeignSession(kTag3));
+  GetTracker()->LookupForeignTabNodeIds(kTag3, &result);
   EXPECT_TRUE(result.empty());
 
-  EXPECT_FALSE(GetTracker()->DeleteSession(tag1));
-  GetTracker()->LookupTabNodeIds(tag1, &result);
+  EXPECT_FALSE(GetTracker()->DeleteForeignSession(kTag));
+  GetTracker()->LookupForeignTabNodeIds(kTag, &result);
   EXPECT_TRUE(result.empty());
-  GetTracker()->LookupTabNodeIds(tag2, &result);
+  GetTracker()->LookupForeignTabNodeIds(kTag2, &result);
   EXPECT_EQ(2U, result.size());
   EXPECT_FALSE(result.end() == result.find(21));
   EXPECT_FALSE(result.end() == result.find(22));
 
-  GetTracker()->GetTab(tag2, 1, 21);
-  GetTracker()->GetTab(tag2, 2, 23);
-  GetTracker()->LookupTabNodeIds(tag2, &result);
+  GetTracker()->OnTabNodeSeen(kTag2, 21);
+  GetTracker()->OnTabNodeSeen(kTag2, 23);
+  GetTracker()->LookupForeignTabNodeIds(kTag2, &result);
   EXPECT_EQ(3U, result.size());
   EXPECT_FALSE(result.end() == result.find(21));
   EXPECT_FALSE(result.end() == result.find(22));
   EXPECT_FALSE(result.end() == result.find(23));
 
-  EXPECT_FALSE(GetTracker()->DeleteSession(tag2));
-  GetTracker()->LookupTabNodeIds(tag2, &result);
+  EXPECT_FALSE(GetTracker()->DeleteForeignSession(kTag2));
+  GetTracker()->LookupForeignTabNodeIds(kTag2, &result);
   EXPECT_TRUE(result.empty());
 }
 
 TEST_F(SyncedSessionTrackerTest, SessionTracking) {
   ASSERT_TRUE(GetTracker()->Empty());
-  std::string tag1 = "tag1";
-  std::string tag2 = "tag2";
 
   // Create some session information that is stale.
-  SyncedSession* session1 = GetTracker()->GetSession(tag1);
-  GetTracker()->PutWindowInSession(tag1, 0);
-  GetTracker()->PutTabInWindow(tag1, 0, 0, 0);
-  GetTracker()->PutTabInWindow(tag1, 0, 1, 1);
-  GetTracker()->GetTab(tag1, 2, 3U)->window_id.set_id(0);  // Will be unmapped.
-  GetTracker()->GetTab(tag1, 3, 4U)->window_id.set_id(0);  // Will be unmapped.
-  GetTracker()->PutWindowInSession(tag1, 1);
-  GetTracker()->PutTabInWindow(tag1, 1, 4, 0);
-  GetTracker()->PutTabInWindow(tag1, 1, 5, 1);
+  SyncedSession* session1 = GetTracker()->GetSession(kTag);
+  GetTracker()->PutWindowInSession(kTag, 0);
+  GetTracker()->PutTabInWindow(kTag, 0, 0);
+  GetTracker()->PutTabInWindow(kTag, 0, 1);
+  GetTracker()->GetTab(kTag, 2)->window_id.set_id(0);  // Will be unmapped.
+  GetTracker()->GetTab(kTag, 3)->window_id.set_id(0);  // Will be unmapped.
+  GetTracker()->PutWindowInSession(kTag, 1);
+  GetTracker()->PutTabInWindow(kTag, 1, 4);
+  GetTracker()->PutTabInWindow(kTag, 1, 5);
   ASSERT_EQ(2U, session1->windows.size());
   ASSERT_EQ(2U, session1->windows[0]->tabs.size());
   ASSERT_EQ(2U, session1->windows[1]->tabs.size());
-  ASSERT_EQ(6U, GetTracker()->num_synced_tabs(tag1));
+  ASSERT_EQ(6U, GetTracker()->num_synced_tabs(kTag));
 
   // Create a session that should not be affected.
-  SyncedSession* session2 = GetTracker()->GetSession(tag2);
-  GetTracker()->PutWindowInSession(tag2, 2);
-  GetTracker()->PutTabInWindow(tag2, 2, 1, 0);
+  SyncedSession* session2 = GetTracker()->GetSession(kTag2);
+  GetTracker()->PutWindowInSession(kTag2, 2);
+  GetTracker()->PutTabInWindow(kTag2, 2, 1);
   ASSERT_EQ(1U, session2->windows.size());
   ASSERT_EQ(1U, session2->windows[2]->tabs.size());
-  ASSERT_EQ(1U, GetTracker()->num_synced_tabs(tag2));
+  ASSERT_EQ(1U, GetTracker()->num_synced_tabs(kTag2));
 
   // Reset tracking and get the current windows/tabs.
   // We simulate moving a tab from one window to another, then closing the
@@ -311,18 +313,18 @@
   // on the remaining window.
 
   // New tab, arrived before meta node so unmapped.
-  GetTracker()->GetTab(tag1, 6, 7U);
-  GetTracker()->ResetSessionTracking(tag1);
-  GetTracker()->PutWindowInSession(tag1, 0);
-  GetTracker()->PutTabInWindow(tag1, 0, 0, 0);
+  GetTracker()->GetTab(kTag, 6);
+  GetTracker()->ResetSessionTracking(kTag);
+  GetTracker()->PutWindowInSession(kTag, 0);
+  GetTracker()->PutTabInWindow(kTag, 0, 0);
   // Tab 1 is closed.
-  GetTracker()->PutTabInWindow(tag1, 0, 2, 1);  // No longer unmapped.
+  GetTracker()->PutTabInWindow(kTag, 0, 2);  // No longer unmapped.
   // Tab 3 was unmapped and does not get used.
-  GetTracker()->PutTabInWindow(tag1, 0, 4, 2);  // Moved from window 1.
+  GetTracker()->PutTabInWindow(kTag, 0, 4);  // Moved from window 1.
   // Window 1 was closed, along with tab 5.
-  GetTracker()->PutTabInWindow(tag1, 0, 6, 3);  // No longer unmapped.
+  GetTracker()->PutTabInWindow(kTag, 0, 6);  // No longer unmapped.
   // Session 2 should not be affected.
-  GetTracker()->CleanupSession(tag1);
+  GetTracker()->CleanupForeignSession(kTag);
 
   // Verify that only those parts of the session not owned have been removed.
   ASSERT_EQ(1U, session1->windows.size());
@@ -330,39 +332,162 @@
   ASSERT_EQ(1U, session2->windows.size());
   ASSERT_EQ(1U, session2->windows[2]->tabs.size());
   ASSERT_EQ(2U, GetTracker()->num_synced_sessions());
-  ASSERT_EQ(4U, GetTracker()->num_synced_tabs(tag1));
-  ASSERT_EQ(1U, GetTracker()->num_synced_tabs(tag2));
+  ASSERT_EQ(4U, GetTracker()->num_synced_tabs(kTag));
+  ASSERT_EQ(1U, GetTracker()->num_synced_tabs(kTag2));
 
   // All memory should be properly deallocated by destructor for the
   // SyncedSessionTracker.
 }
 
 TEST_F(SyncedSessionTrackerTest, DeleteForeignTab) {
-  std::string session_tag = "session_tag";
-  int tab_id_1 = 1;
-  int tab_id_2 = 2;
-  int tab_node_id_3 = 3;
-  int tab_node_id_4 = 4;
+  int tab_node_id_1 = 1;
+  int tab_node_id_2 = 2;
   std::set<int> result;
 
-  GetTracker()->GetTab(session_tag, tab_id_1, tab_node_id_3);
-  GetTracker()->GetTab(session_tag, tab_id_1, tab_node_id_4);
-  GetTracker()->GetTab(session_tag, tab_id_2, tab_node_id_3);
-  GetTracker()->GetTab(session_tag, tab_id_2, tab_node_id_4);
+  GetTracker()->OnTabNodeSeen(kTag, tab_node_id_1);
+  GetTracker()->OnTabNodeSeen(kTag, tab_node_id_2);
 
-  GetTracker()->LookupTabNodeIds(session_tag, &result);
+  GetTracker()->LookupForeignTabNodeIds(kTag, &result);
   EXPECT_EQ(2U, result.size());
-  EXPECT_TRUE(result.find(tab_node_id_3) != result.end());
-  EXPECT_TRUE(result.find(tab_node_id_4) != result.end());
+  EXPECT_TRUE(result.find(tab_node_id_1) != result.end());
+  EXPECT_TRUE(result.find(tab_node_id_2) != result.end());
 
-  GetTracker()->DeleteForeignTab(session_tag, tab_node_id_3);
-  GetTracker()->LookupTabNodeIds(session_tag, &result);
+  GetTracker()->DeleteForeignTab(kTag, tab_node_id_1);
+  GetTracker()->LookupForeignTabNodeIds(kTag, &result);
   EXPECT_EQ(1U, result.size());
-  EXPECT_TRUE(result.find(tab_node_id_4) != result.end());
+  EXPECT_TRUE(result.find(tab_node_id_2) != result.end());
 
-  GetTracker()->DeleteForeignTab(session_tag, tab_node_id_4);
-  GetTracker()->LookupTabNodeIds(session_tag, &result);
+  GetTracker()->DeleteForeignTab(kTag, tab_node_id_2);
+  GetTracker()->LookupForeignTabNodeIds(kTag, &result);
   EXPECT_TRUE(result.empty());
 }
 
+TEST_F(SyncedSessionTrackerTest, CleanupLocalTabs) {
+  std::set<int> free_node_ids;
+  int tab_node_id = TabNodePool::kInvalidTabNodeID;
+  const int kTabNode1 = 1;
+  const int kTabNode2 = 2;
+  const int kTabNode3 = 3;
+
+  GetTracker()->SetLocalSessionTag(kTag);
+
+  // Start with two restored tab nodes.
+  GetTracker()->ReassociateLocalTab(kTabNode1, kTab1);
+  GetTracker()->ReassociateLocalTab(kTabNode2, kTab2);
+  EXPECT_TRUE(GetTabNodePool()->Empty());
+  EXPECT_FALSE(GetTabNodePool()->Full());
+  EXPECT_EQ(2U, GetTabNodePool()->Capacity());
+
+  // Associate with no tabs. The tab pool should now be full.
+  GetTracker()->ResetSessionTracking(kTag);
+  GetTracker()->CleanupLocalTabs(&free_node_ids);
+  EXPECT_TRUE(free_node_ids.empty());
+  EXPECT_TRUE(GetTabNodePool()->Full());
+
+  // Associate with only 1 tab open. A tab node should be reused.
+  GetTracker()->ResetSessionTracking(kTag);
+  GetTracker()->PutWindowInSession(kTag, kWindow1);
+  GetTracker()->PutTabInWindow(kTag, kWindow1, kTab1);
+  EXPECT_TRUE(GetTracker()->GetTabNodeFromLocalTabId(kTab1, &tab_node_id));
+  GetTracker()->CleanupLocalTabs(&free_node_ids);
+  EXPECT_TRUE(free_node_ids.empty());
+
+  // TabNodePool should have one free tab node and one used.
+  EXPECT_EQ(2U, GetTabNodePool()->Capacity());
+  EXPECT_FALSE(GetTabNodePool()->Empty());
+  EXPECT_FALSE(GetTabNodePool()->Full());
+
+  // Simulate a tab opening, which should use the last free tab node.
+  EXPECT_TRUE(GetTracker()->GetTabNodeFromLocalTabId(kTab2, &tab_node_id));
+  EXPECT_TRUE(GetTabNodePool()->Empty());
+
+  // Simulate another tab opening, which should create a new associated tab
+  // node.
+  EXPECT_FALSE(GetTracker()->GetTabNodeFromLocalTabId(kTab3, &tab_node_id));
+  EXPECT_EQ(kTabNode3, tab_node_id);
+  EXPECT_EQ(3U, GetTabNodePool()->Capacity());
+  EXPECT_TRUE(GetTabNodePool()->Empty());
+
+  // Fetching the same tab should return the same tab node id.
+  EXPECT_TRUE(GetTracker()->GetTabNodeFromLocalTabId(kTab3, &tab_node_id));
+  EXPECT_EQ(kTabNode3, tab_node_id);
+  EXPECT_TRUE(GetTabNodePool()->Empty());
+
+  // Associate with no tabs. All tabs should be freed again, and the pool
+  // should now be full.
+  GetTracker()->ResetSessionTracking(kTag);
+  GetTracker()->CleanupLocalTabs(&free_node_ids);
+  EXPECT_TRUE(free_node_ids.empty());
+  EXPECT_TRUE(GetTabNodePool()->Full());
+  EXPECT_FALSE(GetTabNodePool()->Empty());
+}
+
+TEST_F(SyncedSessionTrackerTest, ReassociateTabMapped) {
+  std::set<int> free_node_ids;
+
+  // First create the tab normally.
+  GetTracker()->SetLocalSessionTag(kTag);
+  EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
+  GetTracker()->ReassociateLocalTab(kTabNode, kTab1);
+  EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
+
+  // Map it to a window with the same tab id as it was created with.
+  GetTracker()->ResetSessionTracking(kTag);
+  GetTracker()->PutWindowInSession(kTag, kWindow1);
+  GetTracker()->PutTabInWindow(kTag, kWindow1, kTab1);
+  GetTracker()->CleanupLocalTabs(&free_node_ids);
+  SyncedSession* session = GetTracker()->GetSession(kTag);
+  ASSERT_EQ(1U, session->windows.size());
+  ASSERT_EQ(1U, session->windows[kWindow1]->tabs.size());
+  ASSERT_EQ(GetTracker()->GetTab(kTag, kTab1),
+            session->windows[kWindow1]->tabs[0].get());
+
+  // Then reassociate with a new tab id.
+  GetTracker()->ReassociateLocalTab(kTabNode, kTab2);
+  EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
+
+  // Reset tracking, and put the new tab id into the window.
+  GetTracker()->ResetSessionTracking(kTag);
+  GetTracker()->PutWindowInSession(kTag, kWindow1);
+  GetTracker()->PutTabInWindow(kTag, kWindow1, kTab2);
+  GetTracker()->CleanupLocalTabs(&free_node_ids);
+  EXPECT_TRUE(free_node_ids.empty());
+
+  // Now that it's been mapped, it should be accessible both via the
+  // GetSession as well as the GetTab.
+  ASSERT_EQ(GetTracker()->GetTab(kTag, kTab2),
+            session->windows[kWindow1]->tabs[0].get());
+  ASSERT_EQ(session->tab_node_ids.size(),
+            session->tab_node_ids.count(kTabNode));
+  ASSERT_EQ(1U, GetTabNodePool()->Capacity());
+}
+
+TEST_F(SyncedSessionTrackerTest, ReassociateTabUnmapped) {
+  std::set<int> free_node_ids;
+
+  // First create the old tab in an unmapped state.
+  GetTracker()->SetLocalSessionTag(kTag);
+  EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
+  GetTracker()->ReassociateLocalTab(kTabNode, kTab1);
+  EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
+
+  // Map it to a window, but reassociated with a new tab id.
+  GetTracker()->ResetSessionTracking(kTag);
+  GetTracker()->ReassociateLocalTab(kTabNode, kTab2);
+  EXPECT_TRUE(GetTracker()->IsLocalTabNodeAssociated(kTabNode));
+  GetTracker()->PutWindowInSession(kTag, kWindow1);
+  GetTracker()->PutTabInWindow(kTag, kWindow1, kTab2);
+  GetTracker()->CleanupLocalTabs(&free_node_ids);
+  EXPECT_TRUE(free_node_ids.empty());
+
+  // Now that it's been mapped, it should be accessible both via the
+  // GetSession as well as GetTab.
+  SyncedSession* session = GetTracker()->GetSession(kTag);
+  ASSERT_EQ(GetTracker()->GetTab(kTag, kTab2),
+            session->windows[kWindow1]->tabs[0].get());
+  ASSERT_EQ(session->tab_node_ids.size(),
+            session->tab_node_ids.count(kTabNode));
+  ASSERT_EQ(1U, GetTabNodePool()->Capacity());
+}
+
 }  // namespace sync_sessions
diff --git a/components/sync_sessions/tab_node_pool.cc b/components/sync_sessions/tab_node_pool.cc
index 4067b92..f187d23d 100644
--- a/components/sync_sessions/tab_node_pool.cc
+++ b/components/sync_sessions/tab_node_pool.cc
@@ -4,12 +4,10 @@
 
 #include "components/sync_sessions/tab_node_pool.h"
 
-#include "base/format_macros.h"
+#include <algorithm>
+
 #include "base/logging.h"
-#include "base/strings/stringprintf.h"
 #include "components/sync/base/model_type.h"
-#include "components/sync/model/sync_change.h"
-#include "components/sync/model/sync_data.h"
 #include "components/sync/protocol/session_specifics.pb.h"
 #include "components/sync/protocol/sync.pb.h"
 
@@ -26,114 +24,91 @@
 
 TabNodePool::~TabNodePool() {}
 
-// Static
-std::string TabNodePool::TabIdToTag(const std::string& machine_tag,
-                                    int tab_node_id) {
-  return base::StringPrintf("%s %d", machine_tag.c_str(), tab_node_id);
-}
-
 void TabNodePool::AddTabNode(int tab_node_id) {
   DCHECK_GT(tab_node_id, kInvalidTabNodeID);
   DCHECK(nodeid_tabid_map_.find(tab_node_id) == nodeid_tabid_map_.end());
-  unassociated_nodes_.insert(tab_node_id);
-  if (max_used_tab_node_id_ < tab_node_id)
-    max_used_tab_node_id_ = tab_node_id;
+  DVLOG(1) << "Adding tab node " << tab_node_id << " to pool.";
+  max_used_tab_node_id_ = std::max(max_used_tab_node_id_, tab_node_id);
+  free_nodes_pool_.insert(tab_node_id);
 }
 
 void TabNodePool::AssociateTabNode(int tab_node_id, SessionID::id_type tab_id) {
   DCHECK_GT(tab_node_id, kInvalidTabNodeID);
-  // Remove sync node if it is in unassociated nodes pool.
-  std::set<int>::iterator u_it = unassociated_nodes_.find(tab_node_id);
-  if (u_it != unassociated_nodes_.end()) {
-    unassociated_nodes_.erase(u_it);
-  } else {
-    // This is a new node association, the sync node should be free.
-    // Remove node from free node pool and then associate it with the tab.
-    std::set<int>::iterator it = free_nodes_pool_.find(tab_node_id);
-    DCHECK(it != free_nodes_pool_.end());
-    free_nodes_pool_.erase(it);
-  }
+  DCHECK_GT(tab_id, kInvalidTabID);
+
+  // This is a new node association, the sync node should be free.
+  // Remove node from free node pool and then associate it with the tab.
+  std::set<int>::iterator it = free_nodes_pool_.find(tab_node_id);
+  DCHECK(it != free_nodes_pool_.end());
+  free_nodes_pool_.erase(it);
+
   DCHECK(nodeid_tabid_map_.find(tab_node_id) == nodeid_tabid_map_.end());
+  DVLOG(1) << "Associating tab node " << tab_node_id << " with tab " << tab_id;
   nodeid_tabid_map_[tab_node_id] = tab_id;
+  tabid_nodeid_map_[tab_id] = tab_node_id;
 }
 
-int TabNodePool::GetFreeTabNode(syncer::SyncChangeList* append_changes) {
-  DCHECK_GT(machine_tag_.length(), 0U);
-  DCHECK(append_changes);
+bool TabNodePool::GetTabNodeForTab(SessionID::id_type tab_id,
+                                   int* tab_node_id) {
+  if (tabid_nodeid_map_.find(tab_id) != tabid_nodeid_map_.end()) {
+    *tab_node_id = tabid_nodeid_map_[tab_id];
+    return true;
+  }
+
   if (free_nodes_pool_.empty()) {
     // Tab pool has no free nodes, allocate new one.
-    int tab_node_id = ++max_used_tab_node_id_;
-    std::string tab_node_tag = TabIdToTag(machine_tag_, tab_node_id);
+    *tab_node_id = ++max_used_tab_node_id_;
+    AddTabNode(*tab_node_id);
 
-    // We fill the new node with just enough data so that in case of a crash/bug
-    // we can identify the node as our own on re-association and reuse it.
-    sync_pb::EntitySpecifics entity;
-    sync_pb::SessionSpecifics* specifics = entity.mutable_session();
-    specifics->set_session_tag(machine_tag_);
-    specifics->set_tab_node_id(tab_node_id);
-    append_changes->push_back(syncer::SyncChange(
-        FROM_HERE, syncer::SyncChange::ACTION_ADD,
-        syncer::SyncData::CreateLocalData(tab_node_tag, tab_node_tag, entity)));
-
-    // Grow the pool by 1 since we created a new node.
-    DVLOG(1) << "Adding sync node " << tab_node_id << " to tab node id pool";
-    free_nodes_pool_.insert(tab_node_id);
-    return tab_node_id;
+    AssociateTabNode(*tab_node_id, tab_id);
+    return false;
   } else {
     // Return the next free node.
-    return *free_nodes_pool_.begin();
+    *tab_node_id = *free_nodes_pool_.begin();
+    AssociateTabNode(*tab_node_id, tab_id);
+    return true;
   }
 }
 
-void TabNodePool::FreeTabNode(int tab_node_id,
-                              syncer::SyncChangeList* append_changes) {
-  DCHECK(append_changes);
-  TabNodeIDToTabIDMap::iterator it = nodeid_tabid_map_.find(tab_node_id);
-  DCHECK(it != nodeid_tabid_map_.end());
-  nodeid_tabid_map_.erase(it);
-  FreeTabNodeInternal(tab_node_id, append_changes);
-}
+void TabNodePool::FreeTab(int tab_id) {
+  DCHECK_GT(tab_id, kInvalidTabID);
+  TabIDToTabNodeIDMap::iterator it = tabid_nodeid_map_.find(tab_id);
+  if (it == tabid_nodeid_map_.end()) {
+    return;  // Already freed.
+  }
 
-void TabNodePool::FreeTabNodeInternal(int tab_node_id,
-                                      syncer::SyncChangeList* append_changes) {
-  DCHECK(free_nodes_pool_.find(tab_node_id) == free_nodes_pool_.end());
-  DCHECK(append_changes);
+  int tab_node_id = it->second;
+  DVLOG(1) << "Freeing tab " << tab_id << " at node " << tab_node_id;
+  nodeid_tabid_map_.erase(nodeid_tabid_map_.find(tab_node_id));
+  tabid_nodeid_map_.erase(it);
   free_nodes_pool_.insert(tab_node_id);
-
-  // If number of free nodes exceed kFreeNodesHighWatermark,
-  // delete sync nodes till number reaches kFreeNodesLowWatermark.
-  // Note: This logic is to mitigate temporary disassociation issues with old
-  // clients: http://crbug.com/259918. Newer versions do not need this.
-  if (free_nodes_pool_.size() > kFreeNodesHighWatermark) {
-    for (std::set<int>::iterator free_it = free_nodes_pool_.begin();
-         free_it != free_nodes_pool_.end();) {
-      const std::string tab_node_tag = TabIdToTag(machine_tag_, *free_it);
-      append_changes->push_back(syncer::SyncChange(
-          FROM_HERE, syncer::SyncChange::ACTION_DELETE,
-          syncer::SyncData::CreateLocalDelete(tab_node_tag, syncer::SESSIONS)));
-      free_nodes_pool_.erase(free_it++);
-      if (free_nodes_pool_.size() <= kFreeNodesLowWatermark) {
-        return;
-      }
-    }
-  }
-}
-
-bool TabNodePool::IsUnassociatedTabNode(int tab_node_id) {
-  return unassociated_nodes_.find(tab_node_id) != unassociated_nodes_.end();
 }
 
 void TabNodePool::ReassociateTabNode(int tab_node_id,
                                      SessionID::id_type tab_id) {
-  // Remove from list of unassociated sync_nodes if present.
-  std::set<int>::iterator it = unassociated_nodes_.find(tab_node_id);
-  if (it != unassociated_nodes_.end()) {
-    unassociated_nodes_.erase(it);
-  } else {
-    // tab_node_id must be an already associated node.
-    DCHECK(nodeid_tabid_map_.find(tab_node_id) != nodeid_tabid_map_.end());
+  DCHECK_GT(tab_node_id, kInvalidTabNodeID);
+  DCHECK_GT(tab_id, kInvalidTabID);
+
+  auto tabid_it = tabid_nodeid_map_.find(tab_id);
+  if (tabid_it != tabid_nodeid_map_.end()) {
+    if (tabid_it->second == tab_node_id) {
+      return;  // Already associated properly.
+    } else {
+      // Another node is already associated with this tab. Free it.
+      FreeTab(tab_id);
+    }
   }
-  nodeid_tabid_map_[tab_node_id] = tab_id;
+
+  auto nodeid_it = nodeid_tabid_map_.find(tab_node_id);
+  if (nodeid_it != nodeid_tabid_map_.end()) {
+    // This node was already associated with another tab. Free it.
+    FreeTab(nodeid_it->second);
+  } else {
+    // This is a new tab node. Add it before association.
+    AddTabNode(tab_node_id);
+  }
+
+  AssociateTabNode(tab_node_id, tab_id);
 }
 
 SessionID::id_type TabNodePool::GetTabIdFromTabNodeId(int tab_node_id) const {
@@ -144,27 +119,33 @@
   return kInvalidTabID;
 }
 
-void TabNodePool::DeleteUnassociatedTabNodes(
-    syncer::SyncChangeList* append_changes) {
-  for (std::set<int>::iterator it = unassociated_nodes_.begin();
-       it != unassociated_nodes_.end();) {
-    FreeTabNodeInternal(*it, append_changes);
-    unassociated_nodes_.erase(it++);
+void TabNodePool::CleanupTabNodes(std::set<int>* deleted_node_ids) {
+  // If number of free nodes exceed kFreeNodesHighWatermark,
+  // delete sync nodes till number reaches kFreeNodesLowWatermark.
+  // Note: This logic is to mitigate temporary disassociation issues with old
+  // clients: http://crbug.com/259918. Newer versions do not need this.
+  if (free_nodes_pool_.size() > kFreeNodesHighWatermark) {
+    for (std::set<int>::iterator free_it = free_nodes_pool_.begin();
+         free_it != free_nodes_pool_.end();) {
+      deleted_node_ids->insert(*free_it);
+      free_nodes_pool_.erase(free_it++);
+      if (free_nodes_pool_.size() <= kFreeNodesLowWatermark) {
+        return;
+      }
+    }
   }
-  DCHECK(unassociated_nodes_.empty());
 }
 
 // Clear tab pool.
 void TabNodePool::Clear() {
-  unassociated_nodes_.clear();
   free_nodes_pool_.clear();
   nodeid_tabid_map_.clear();
+  tabid_nodeid_map_.clear();
   max_used_tab_node_id_ = kInvalidTabNodeID;
 }
 
 size_t TabNodePool::Capacity() const {
-  return nodeid_tabid_map_.size() + unassociated_nodes_.size() +
-         free_nodes_pool_.size();
+  return nodeid_tabid_map_.size() + free_nodes_pool_.size();
 }
 
 bool TabNodePool::Empty() const {
@@ -175,8 +156,4 @@
   return nodeid_tabid_map_.empty();
 }
 
-void TabNodePool::SetMachineTag(const std::string& machine_tag) {
-  machine_tag_ = machine_tag;
-}
-
 }  // namespace sync_sessions
diff --git a/components/sync_sessions/tab_node_pool.h b/components/sync_sessions/tab_node_pool.h
index caadc4e..833daf7 100644
--- a/components/sync_sessions/tab_node_pool.h
+++ b/components/sync_sessions/tab_node_pool.h
@@ -13,11 +13,6 @@
 
 #include "base/macros.h"
 #include "components/sessions/core/session_id.h"
-#include "components/sync/model/sync_change_processor.h"
-
-namespace syncer {
-class SyncChangeProcessor;
-}  // namespace syncer
 
 namespace sync_sessions {
 
@@ -27,17 +22,11 @@
 // - a tab_id: created by session service, unique to this client
 // - a tab_node_id: the id for a particular sync tab node. This is used
 //   to generate the sync tab node tag through:
-//       tab_tag = StringPrintf("%s_%ui", local_session_tag, tab_node_id);
+//       tab_tag = StringPrintf("%s %d", local_session_tag, tab_node_id);
 //
-// A sync node can be in one of the three states:
+// A sync node can be in one of the two states:
 // 1. Associated   : Sync node is used and associated with a tab.
-// 2. Unassociated : Sync node is used but currently unassociated with any tab.
-//                   This is true for old nodes that remain from a session
-//                   restart. Nodes are only unassociated temporarily while the
-//                   model associator figures out which tabs belong to which
-//                   nodes. Eventually any remaining unassociated nodes are
-//                   freed.
-// 3. Free         : Sync node is unused.
+// 2. Free         : Sync node is unused.
 
 class TabNodePool {
  public:
@@ -54,65 +43,37 @@
 
   static const int kInvalidTabNodeID;
 
-  // Build a sync tag from tab_node_id.
-  static std::string TabIdToTag(const std::string& machine_tag,
-                                int tab_node_id);
-
-  // Returns the tab_node_id for the next free tab node. If none are available,
-  // creates a new tab node and adds it to free nodes pool. The free node can
-  // then be used to associate with a tab by calling AssociateTabNode.
-  // Note: The node is considered free until it has been associated. Repeated
-  // calls to GetFreeTabNode will return the same id until node has been
-  // associated.
-  // |change_output| *must* be provided. It is the TabNodePool's link to
-  // the SyncChange pipeline that exists in the caller context. If the need
-  // to create nodes arises in the implementation, associated SyncChanges will
-  // be appended to this list for later application by the caller via the
-  // SyncChangeProcessor.
-  int GetFreeTabNode(syncer::SyncChangeList* change_output);
-
-  // Removes association for |tab_node_id| and returns it to the free node pool.
-  // |change_output| *must* be provided. It is the TabNodePool's link to
-  // the SyncChange pipeline that exists in the caller's context. If the need
-  // to delete sync nodes arises in the implementation, associated SyncChanges
-  // will be appended to this list for later application by the caller via the
-  // SyncChangeProcessor.
-  void FreeTabNode(int tab_node_id, syncer::SyncChangeList* change_output);
-
-  // Associates |tab_node_id| with |tab_id|. |tab_node_id| should either be
-  // unassociated or free. If |tab_node_id| is free, |tab_node_id| is removed
-  // from the free node pool In order to associate a non free sync node,
-  // use ReassociateTabNode.
-  void AssociateTabNode(int tab_node_id, SessionID::id_type tab_id);
-
-  // Adds |tab_node_id| as an unassociated sync node.
-  // Note: this should only be called when we discover tab sync nodes from
-  // previous sessions, not for freeing tab nodes we created through
-  // GetFreeTabNode (use FreeTabNode below for that).
-  void AddTabNode(int tab_node_id);
+  // Fills |tab_node_id| with a tab node associated with |tab_id|.
+  // If tab_id is already associated with a tab_node_id, reuses the existing
+  // association. Otherwise attempts to get the next free tab node and
+  // associate it with |tab_id|. If none are available, will create a new tab
+  // node.
+  // Returns true if a pre-existing tab node could be reused, false if a new one
+  // had to be created.
+  bool GetTabNodeForTab(SessionID::id_type tab_id, int* tab_node_id);
 
   // Returns the tab_id for |tab_node_id| if it is associated else returns
   // kInvalidTabID.
   SessionID::id_type GetTabIdFromTabNodeId(int tab_node_id) const;
 
-  // Reassociates |tab_node_id| with |tab_id|. |tab_node_id| must be either
-  // associated with a tab or in the set of unassociated nodes.
+  // Reassociates |tab_node_id| with |tab_id|. If |tab_node_id| is not already
+  // known, it is added to the tab node pool before being associated.
   void ReassociateTabNode(int tab_node_id, SessionID::id_type tab_id);
 
-  // Returns true if |tab_node_id| is an unassociated tab node.
-  bool IsUnassociatedTabNode(int tab_node_id);
+  // Removes association for |tab_id| and returns its tab node to the free node
+  // pool.
+  void FreeTab(int tab_id);
 
-  // Returns any unassociated nodes to the free node pool.
-  // |change_output| *must* be provided. It is the TabNodePool's link to
-  // the SyncChange pipeline that exists in the caller's context.
-  // See FreeTabNode for more detail.
-  void DeleteUnassociatedTabNodes(syncer::SyncChangeList* change_output);
+  // Fills |deleted_node_ids| with any free nodes to be deleted as proscribed
+  // by the free node low/high watermarks, in order to ensure the free node pool
+  // does not grow too large.
+  void CleanupTabNodes(std::set<int>* deleted_node_ids);
 
   // Clear tab pool.
   void Clear();
 
   // Return the number of tab nodes this client currently has allocated
-  // (including both free, unassociated and associated nodes)
+  // (including both free and associated nodes).
   size_t Capacity() const;
 
   // Return empty status (all tab nodes are in use).
@@ -121,41 +82,36 @@
   // Return full status (no tab nodes are in use).
   bool Full();
 
-  void SetMachineTag(const std::string& machine_tag);
-
  private:
   friend class SyncTabNodePoolTest;
   typedef std::map<int, SessionID::id_type> TabNodeIDToTabIDMap;
+  typedef std::map<SessionID::id_type, int> TabIDToTabNodeIDMap;
 
-  // Adds |tab_node_id| to free node pool.
-  // |change_output| *must* be provided. It is the TabNodePool's link to
-  // the SyncChange pipeline that exists in the caller's context.
-  // See FreeTabNode for more detail.
-  void FreeTabNodeInternal(int tab_node_id,
-                           syncer::SyncChangeList* change_output);
+  // Adds |tab_node_id| to the tab node pool.
+  // Note: this should only be called when we discover tab sync nodes from
+  // previous sessions, not for freeing tab nodes we created through
+  // GetTabNodeForTab (use FreeTab for that).
+  void AddTabNode(int tab_node_id);
+
+  // Associates |tab_node_id| with |tab_id|. |tab_node_id| must be free. In
+  // order to associated a non-free tab node, ReassociateTabNode must be
+  // used.
+  void AssociateTabNode(int tab_node_id, SessionID::id_type tab_id);
 
   // Stores mapping of node ids associated with tab_ids, these are the used
   // nodes of tab node pool.
   // The nodes in the map can be returned to free tab node pool by calling
-  // FreeTabNode(tab_node_id).
+  // FreeTab(..).
   TabNodeIDToTabIDMap nodeid_tabid_map_;
+  TabIDToTabNodeIDMap tabid_nodeid_map_;
 
   // The node ids for the set of free sync nodes.
   std::set<int> free_nodes_pool_;
 
-  // The node ids that are added to pool using AddTabNode and are currently
-  // not associated with any tab. They can be reassociated using
-  // ReassociateTabNode.
-  std::set<int> unassociated_nodes_;
-
   // The maximum used tab_node id for a sync node. A new sync node will always
   // be created with max_used_tab_node_id_ + 1.
   int max_used_tab_node_id_;
 
-  // The machine tag associated with this tab pool. Used in the title of new
-  // sync nodes.
-  std::string machine_tag_;
-
   DISALLOW_COPY_AND_ASSIGN(TabNodePool);
 };
 
diff --git a/components/sync_sessions/tab_node_pool_unittest.cc b/components/sync_sessions/tab_node_pool_unittest.cc
index cd125a2..591c8b54 100644
--- a/components/sync_sessions/tab_node_pool_unittest.cc
+++ b/components/sync_sessions/tab_node_pool_unittest.cc
@@ -6,16 +6,13 @@
 
 #include <vector>
 
-#include "components/sync/model/sync_change.h"
-#include "components/sync/protocol/session_specifics.pb.h"
-#include "components/sync/protocol/sync.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace sync_sessions {
 
 class SyncTabNodePoolTest : public testing::Test {
  protected:
-  SyncTabNodePoolTest() { pool_.SetMachineTag("tag"); }
+  SyncTabNodePoolTest() {}
 
   int GetMaxUsedTabNodeId() const { return pool_.max_used_tab_node_id_; }
 
@@ -32,107 +29,127 @@
 
 namespace {
 
+const int kTabNodeId1 = 10;
+const int kTabNodeId2 = 5;
+const int kTabNodeId3 = 1000;
+const int kTabId1 = 1;
+const int kTabId2 = 2;
+const int kTabId3 = 3;
+
 TEST_F(SyncTabNodePoolTest, TabNodeIdIncreases) {
-  syncer::SyncChangeList changes;
+  std::set<int> deleted_node_ids;
+
   // max_used_tab_node_ always increases.
-  pool_.AddTabNode(10);
-  EXPECT_EQ(10, GetMaxUsedTabNodeId());
-  pool_.AddTabNode(5);
-  EXPECT_EQ(10, GetMaxUsedTabNodeId());
-  pool_.AddTabNode(1000);
-  EXPECT_EQ(1000, GetMaxUsedTabNodeId());
-  pool_.ReassociateTabNode(1000, 1);
-  pool_.ReassociateTabNode(5, 2);
-  pool_.ReassociateTabNode(10, 3);
+  pool_.ReassociateTabNode(kTabNodeId1, kTabId1);
+  EXPECT_EQ(kTabNodeId1, GetMaxUsedTabNodeId());
+  pool_.ReassociateTabNode(kTabNodeId2, kTabId2);
+  EXPECT_EQ(kTabNodeId1, GetMaxUsedTabNodeId());
+  pool_.ReassociateTabNode(kTabNodeId3, kTabId3);
+  EXPECT_EQ(kTabNodeId3, GetMaxUsedTabNodeId());
   // Freeing a tab node does not change max_used_tab_node_id_.
-  pool_.FreeTabNode(1000, &changes);
-  EXPECT_TRUE(changes.empty());
-  pool_.FreeTabNode(5, &changes);
-  EXPECT_TRUE(changes.empty());
-  pool_.FreeTabNode(10, &changes);
-  EXPECT_TRUE(changes.empty());
+  pool_.FreeTab(kTabId3);
+  pool_.CleanupTabNodes(&deleted_node_ids);
+  EXPECT_TRUE(deleted_node_ids.empty());
+  pool_.FreeTab(kTabId2);
+  pool_.CleanupTabNodes(&deleted_node_ids);
+  EXPECT_TRUE(deleted_node_ids.empty());
+  pool_.FreeTab(kTabId1);
+  pool_.CleanupTabNodes(&deleted_node_ids);
+  EXPECT_TRUE(deleted_node_ids.empty());
   for (int i = 0; i < 3; ++i) {
-    pool_.AssociateTabNode(pool_.GetFreeTabNode(&changes), i + 1);
-    EXPECT_EQ(1000, GetMaxUsedTabNodeId());
+    int tab_node_id = -1;
+    EXPECT_TRUE(pool_.GetTabNodeForTab(i + 1, &tab_node_id));
+    EXPECT_EQ(kTabNodeId3, GetMaxUsedTabNodeId());
   }
-  EXPECT_TRUE(changes.empty());
-  EXPECT_EQ(1000, GetMaxUsedTabNodeId());
+  pool_.CleanupTabNodes(&deleted_node_ids);
+  EXPECT_TRUE(deleted_node_ids.empty());
+  EXPECT_EQ(kTabNodeId3, GetMaxUsedTabNodeId());
   EXPECT_TRUE(pool_.Empty());
 }
 
-TEST_F(SyncTabNodePoolTest, OldTabNodesAddAndRemove) {
-  syncer::SyncChangeList changes;
-  // VerifyOldTabNodes are added.
-  pool_.AddTabNode(1);
-  pool_.AddTabNode(2);
-  EXPECT_EQ(2u, pool_.Capacity());
+TEST_F(SyncTabNodePoolTest, Reassociation) {
+  // Reassociate tab node 1 with tab id 1.
+  pool_.ReassociateTabNode(kTabNodeId1, kTabId1);
+  EXPECT_EQ(1U, pool_.Capacity());
   EXPECT_TRUE(pool_.Empty());
-  EXPECT_TRUE(pool_.IsUnassociatedTabNode(1));
-  EXPECT_TRUE(pool_.IsUnassociatedTabNode(2));
-  pool_.ReassociateTabNode(1, 2);
-  EXPECT_TRUE(pool_.Empty());
-  pool_.AssociateTabNode(2, 3);
-  EXPECT_FALSE(pool_.IsUnassociatedTabNode(1));
-  EXPECT_FALSE(pool_.IsUnassociatedTabNode(2));
-  pool_.FreeTabNode(2, &changes);
-  EXPECT_TRUE(changes.empty());
-  // 2 should be returned to free node pool_.
-  EXPECT_EQ(2u, pool_.Capacity());
-  // Should be able to free 1.
-  pool_.FreeTabNode(1, &changes);
+  EXPECT_FALSE(pool_.Full());
+  EXPECT_EQ(kTabId1, pool_.GetTabIdFromTabNodeId(kTabNodeId1));
+  EXPECT_EQ(TabNodePool::kInvalidTabNodeID,
+            pool_.GetTabIdFromTabNodeId(kTabNodeId2));
+
+  // Introduce a new tab node associated with the same tab. The old tab node
+  // should get added to the free pool
+  pool_.ReassociateTabNode(kTabNodeId2, kTabId1);
+  EXPECT_EQ(2U, pool_.Capacity());
   EXPECT_FALSE(pool_.Empty());
-  EXPECT_TRUE(pool_.Full());
-  EXPECT_EQ(1, pool_.GetFreeTabNode(&changes));
-  EXPECT_TRUE(changes.empty());
-  pool_.AssociateTabNode(1, 1);
-  EXPECT_EQ(2, pool_.GetFreeTabNode(&changes));
-  EXPECT_TRUE(changes.empty());
-  pool_.AssociateTabNode(2, 1);
+  EXPECT_FALSE(pool_.Full());
+  EXPECT_EQ(TabNodePool::kInvalidTabNodeID,
+            pool_.GetTabIdFromTabNodeId(kTabNodeId1));
+  EXPECT_EQ(kTabId1, pool_.GetTabIdFromTabNodeId(kTabNodeId2));
+
+  // Reassociating the same tab node/tab should have no effect.
+  pool_.ReassociateTabNode(kTabNodeId2, kTabId1);
+  EXPECT_EQ(2U, pool_.Capacity());
+  EXPECT_FALSE(pool_.Empty());
+  EXPECT_FALSE(pool_.Full());
+  EXPECT_EQ(TabNodePool::kInvalidTabNodeID,
+            pool_.GetTabIdFromTabNodeId(kTabNodeId1));
+  EXPECT_EQ(kTabId1, pool_.GetTabIdFromTabNodeId(kTabNodeId2));
+
+  // Reassociating the new tab node with a new tab should just update the
+  // association tables.
+  pool_.ReassociateTabNode(kTabNodeId2, kTabId2);
+  EXPECT_EQ(2U, pool_.Capacity());
+  EXPECT_FALSE(pool_.Empty());
+  EXPECT_FALSE(pool_.Full());
+  EXPECT_EQ(TabNodePool::kInvalidTabNodeID,
+            pool_.GetTabIdFromTabNodeId(kTabNodeId1));
+  EXPECT_EQ(kTabId2, pool_.GetTabIdFromTabNodeId(kTabNodeId2));
+
+  // Reassociating the first tab node should make the pool empty.
+  pool_.ReassociateTabNode(kTabNodeId1, kTabId1);
+  EXPECT_EQ(2U, pool_.Capacity());
   EXPECT_TRUE(pool_.Empty());
   EXPECT_FALSE(pool_.Full());
-  EXPECT_FALSE(pool_.Full());
+  EXPECT_EQ(kTabId1, pool_.GetTabIdFromTabNodeId(kTabNodeId1));
+  EXPECT_EQ(kTabId2, pool_.GetTabIdFromTabNodeId(kTabNodeId2));
 }
 
-TEST_F(SyncTabNodePoolTest, OldTabNodesReassociation) {
-  // VerifyOldTabNodes are reassociated correctly.
-  pool_.AddTabNode(4);
-  pool_.AddTabNode(5);
-  pool_.AddTabNode(6);
+TEST_F(SyncTabNodePoolTest, ReassociateThenFree) {
+  std::set<int> deleted_node_ids;
+
+  // Verify old tab nodes are reassociated correctly.
+  pool_.ReassociateTabNode(kTabNodeId1, kTabId1);
+  pool_.ReassociateTabNode(kTabNodeId2, kTabId2);
+  pool_.ReassociateTabNode(kTabNodeId3, kTabId3);
   EXPECT_EQ(3u, pool_.Capacity());
   EXPECT_TRUE(pool_.Empty());
-  EXPECT_TRUE(pool_.IsUnassociatedTabNode(4));
-  pool_.ReassociateTabNode(4, 5);
-  pool_.AssociateTabNode(5, 6);
-  pool_.AssociateTabNode(6, 7);
-  // Free 5 and 6.
-  syncer::SyncChangeList changes;
-  pool_.FreeTabNode(5, &changes);
-  pool_.FreeTabNode(6, &changes);
-  EXPECT_TRUE(changes.empty());
-  // 5 and 6 nodes should not be unassociated.
-  EXPECT_FALSE(pool_.IsUnassociatedTabNode(5));
-  EXPECT_FALSE(pool_.IsUnassociatedTabNode(6));
-  // Free node pool should have 5 and 6.
+  // Free tabs 2 and 3.
+  pool_.FreeTab(kTabId2);
+  pool_.FreeTab(kTabId3);
+  pool_.CleanupTabNodes(&deleted_node_ids);
+  EXPECT_TRUE(deleted_node_ids.empty());
+  // Free node pool should have 2 and 3.
   EXPECT_FALSE(pool_.Empty());
   EXPECT_EQ(3u, pool_.Capacity());
 
   // Free all nodes
-  pool_.FreeTabNode(4, &changes);
-  EXPECT_TRUE(changes.empty());
+  pool_.FreeTab(kTabId1);
+  pool_.CleanupTabNodes(&deleted_node_ids);
+  EXPECT_TRUE(deleted_node_ids.empty());
   EXPECT_TRUE(pool_.Full());
   std::set<int> free_sync_ids;
   for (int i = 0; i < 3; ++i) {
-    free_sync_ids.insert(pool_.GetFreeTabNode(&changes));
-    // GetFreeTabNode will return the same value till the node is
-    // reassociated.
-    pool_.AssociateTabNode(pool_.GetFreeTabNode(&changes), i + 1);
+    int tab_node_id = -1;
+    EXPECT_TRUE(pool_.GetTabNodeForTab(i, &tab_node_id));
+    free_sync_ids.insert(tab_node_id);
   }
 
   EXPECT_TRUE(pool_.Empty());
   EXPECT_EQ(3u, free_sync_ids.size());
-  EXPECT_EQ(1u, free_sync_ids.count(4));
-  EXPECT_EQ(1u, free_sync_ids.count(5));
-  EXPECT_EQ(1u, free_sync_ids.count(6));
+  EXPECT_EQ(1u, free_sync_ids.count(kTabNodeId1));
+  EXPECT_EQ(1u, free_sync_ids.count(kTabNodeId2));
+  EXPECT_EQ(1u, free_sync_ids.count(kTabNodeId3));
 }
 
 TEST_F(SyncTabNodePoolTest, Init) {
@@ -141,106 +158,49 @@
 }
 
 TEST_F(SyncTabNodePoolTest, AddGet) {
-  syncer::SyncChangeList changes;
   int free_nodes[] = {5, 10};
   AddFreeTabNodes(2, free_nodes);
 
   EXPECT_EQ(2U, pool_.Capacity());
-  EXPECT_EQ(5, pool_.GetFreeTabNode(&changes));
-  pool_.AssociateTabNode(5, 1);
+  int tab_node_id = -1;
+  EXPECT_TRUE(pool_.GetTabNodeForTab(1, &tab_node_id));
+  EXPECT_EQ(5, tab_node_id);
   EXPECT_FALSE(pool_.Empty());
   EXPECT_FALSE(pool_.Full());
   EXPECT_EQ(2U, pool_.Capacity());
   // 5 is now used, should return 10.
-  EXPECT_EQ(10, pool_.GetFreeTabNode(&changes));
+  EXPECT_TRUE(pool_.GetTabNodeForTab(2, &tab_node_id));
+  EXPECT_EQ(10, tab_node_id);
 }
 
-TEST_F(SyncTabNodePoolTest, All) {
-  syncer::SyncChangeList changes;
-  EXPECT_TRUE(pool_.Empty());
-  EXPECT_TRUE(pool_.Full());
-  EXPECT_EQ(0U, pool_.Capacity());
-
-  // GetFreeTabNode returns the lowest numbered free node.
-  EXPECT_EQ(0, pool_.GetFreeTabNode(&changes));
-  EXPECT_EQ(1U, changes.size());
-  EXPECT_FALSE(pool_.Empty());
-  EXPECT_TRUE(pool_.Full());
-  EXPECT_EQ(1U, pool_.Capacity());
-
-  // Associate 5, next free node should be 10.
-  pool_.AssociateTabNode(0, 1);
-  EXPECT_EQ(1, pool_.GetFreeTabNode(&changes));
-  EXPECT_EQ(2U, changes.size());
-  changes.clear();
-  pool_.AssociateTabNode(1, 2);
-  EXPECT_TRUE(pool_.Empty());
-  EXPECT_FALSE(pool_.Full());
-  EXPECT_EQ(2U, pool_.Capacity());
-  // Release them in reverse order.
-  pool_.FreeTabNode(1, &changes);
-  pool_.FreeTabNode(0, &changes);
-  EXPECT_EQ(2U, pool_.Capacity());
-  EXPECT_FALSE(pool_.Empty());
-  EXPECT_TRUE(pool_.Full());
-  EXPECT_EQ(0, pool_.GetFreeTabNode(&changes));
-  EXPECT_TRUE(changes.empty());
-  EXPECT_FALSE(pool_.Empty());
-  EXPECT_TRUE(pool_.Full());
-  EXPECT_EQ(2U, pool_.Capacity());
-  EXPECT_FALSE(pool_.Empty());
-  EXPECT_TRUE(pool_.Full());
-  pool_.AssociateTabNode(0, 1);
-  EXPECT_EQ(2U, pool_.Capacity());
-  EXPECT_EQ(1, pool_.GetFreeTabNode(&changes));
-  EXPECT_TRUE(changes.empty());
-  pool_.AssociateTabNode(1, 2);
-  EXPECT_TRUE(pool_.Empty());
-  EXPECT_FALSE(pool_.Full());
-  EXPECT_EQ(2U, pool_.Capacity());
-  // Release them again.
-  pool_.FreeTabNode(1, &changes);
-  pool_.FreeTabNode(0, &changes);
-  EXPECT_FALSE(pool_.Empty());
-  EXPECT_TRUE(pool_.Full());
-  EXPECT_EQ(2U, pool_.Capacity());
-  pool_.Clear();
-  EXPECT_TRUE(pool_.Empty());
-  EXPECT_TRUE(pool_.Full());
-  EXPECT_EQ(0U, pool_.Capacity());
-}
-
-TEST_F(SyncTabNodePoolTest, GetFreeTabNodeCreate) {
-  syncer::SyncChangeList changes;
-  EXPECT_EQ(0, pool_.GetFreeTabNode(&changes));
-  EXPECT_TRUE(changes[0].IsValid());
-  EXPECT_EQ(syncer::SyncChange::ACTION_ADD, changes[0].change_type());
-  EXPECT_TRUE(changes[0].sync_data().IsValid());
-  sync_pb::EntitySpecifics entity = changes[0].sync_data().GetSpecifics();
-  sync_pb::SessionSpecifics specifics(entity.session());
-  EXPECT_EQ(0, specifics.tab_node_id());
+TEST_F(SyncTabNodePoolTest, GetTabNodeForTabCreate) {
+  int tab_node_id = -1;
+  EXPECT_FALSE(pool_.GetTabNodeForTab(1, &tab_node_id));
+  EXPECT_EQ(0, tab_node_id);
 }
 
 TEST_F(SyncTabNodePoolTest, TabPoolFreeNodeLimits) {
+  std::set<int> deleted_node_ids;
+
   // Allocate TabNodePool::kFreeNodesHighWatermark + 1 nodes and verify that
   // freeing the last node reduces the free node pool size to
   // kFreeNodesLowWatermark.
-  syncer::SyncChangeList changes;
   SessionID session_id;
   std::vector<int> used_sync_ids;
   for (size_t i = 1; i <= TabNodePool::kFreeNodesHighWatermark + 1; ++i) {
     session_id.set_id(i);
-    int sync_id = pool_.GetFreeTabNode(&changes);
-    pool_.AssociateTabNode(sync_id, i);
+    int sync_id = -1;
+    EXPECT_FALSE(pool_.GetTabNodeForTab(i, &sync_id));
     used_sync_ids.push_back(sync_id);
   }
 
   // Free all except one node.
-  int last_sync_id = used_sync_ids.back();
   used_sync_ids.pop_back();
 
-  for (size_t i = 0; i < used_sync_ids.size(); ++i) {
-    pool_.FreeTabNode(used_sync_ids[i], &changes);
+  for (size_t i = 1; i <= used_sync_ids.size(); ++i) {
+    pool_.FreeTab(i);
+    pool_.CleanupTabNodes(&deleted_node_ids);
+    EXPECT_TRUE(deleted_node_ids.empty());
   }
 
   // Except one node all nodes should be in FreeNode pool.
@@ -251,7 +211,11 @@
 
   // Freeing the last sync node should drop the free nodes to
   // kFreeNodesLowWatermark.
-  pool_.FreeTabNode(last_sync_id, &changes);
+  pool_.FreeTab(TabNodePool::kFreeNodesHighWatermark + 1);
+  pool_.CleanupTabNodes(&deleted_node_ids);
+  EXPECT_EQ(TabNodePool::kFreeNodesHighWatermark + 1 -
+                TabNodePool::kFreeNodesLowWatermark,
+            deleted_node_ids.size());
   EXPECT_FALSE(pool_.Empty());
   EXPECT_TRUE(pool_.Full());
   EXPECT_EQ(TabNodePool::kFreeNodesLowWatermark, pool_.Capacity());
diff --git a/components/test_runner/web_frame_test_client.cc b/components/test_runner/web_frame_test_client.cc
index 47bc588d..ca0aa87 100644
--- a/components/test_runner/web_frame_test_client.cc
+++ b/components/test_runner/web_frame_test_client.cc
@@ -538,6 +538,12 @@
 
 void WebFrameTestClient::willSendRequest(blink::WebLocalFrame* frame,
                                          blink::WebURLRequest& request) {
+  // PlzNavigate
+  // Navigation requests initiated by the renderer will have been logged when
+  // the navigation was sent to the browser. Please see
+  // the RenderFrameImpl::BeginNavigation() function.
+  if (delegate_->IsNavigationInitiatedByRenderer(request))
+    return;
   // Need to use GURL for host() and SchemeIs()
   GURL url = request.url();
   std::string request_url = url.possibly_invalid_spec();
diff --git a/components/test_runner/web_test_delegate.h b/components/test_runner/web_test_delegate.h
index 2cdbefa9..8350dba 100644
--- a/components/test_runner/web_test_delegate.h
+++ b/components/test_runner/web_test_delegate.h
@@ -32,6 +32,7 @@
 class WebPlugin;
 struct WebPluginParams;
 struct WebSize;
+class WebURLRequest;
 class WebURLResponse;
 class WebView;
 }
@@ -291,6 +292,11 @@
   // Forces a text input state update for the client of WebFrameWidget
   // associated with |frame|.
   virtual void ForceTextInputStateUpdate(blink::WebFrame* frame) = 0;
+
+  // PlzNavigate
+  // Indicates if the navigation was initiated by the browser or renderer.
+  virtual bool IsNavigationInitiatedByRenderer(
+      const blink::WebURLRequest& request) = 0;
 };
 
 }  // namespace test_runner
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc
index 514cc36..8300433 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -479,6 +479,21 @@
   }
 }
 
+gfx::Point BrowserPluginGuest::GetCoordinatesInEmbedderWebContents(
+    const gfx::Point& relative_point) {
+  RenderWidgetHostView* owner_rwhv = GetOwnerRenderWidgetHostView();
+  if (!owner_rwhv)
+    return relative_point;
+
+  gfx::Point point(relative_point);
+
+  // Add the offset form the embedder web contents view.
+  point +=
+      owner_rwhv->TransformPointToRootCoordSpace(guest_window_rect_.origin())
+          .OffsetFromOrigin();
+  return point;
+}
+
 WebContentsImpl* BrowserPluginGuest::GetWebContents() const {
   return static_cast<WebContentsImpl*>(web_contents());
 }
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h
index dd23cd7e..aa9c826 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.h
+++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -257,6 +257,9 @@
     return can_use_cross_process_frames_;
   }
 
+  gfx::Point GetCoordinatesInEmbedderWebContents(
+      const gfx::Point& relative_point);
+
  protected:
 
   // BrowserPluginGuest is a WebContentsObserver of |web_contents| and
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc
index 44547e2d..fd595cf 100644
--- a/content/browser/frame_host/navigation_handle_impl.cc
+++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -193,6 +193,10 @@
   return was_redirected_;
 }
 
+const std::vector<GURL>& NavigationHandleImpl::GetRedirectChain() {
+  return redirect_chain_;
+}
+
 int NavigationHandleImpl::GetFrameTreeNodeId() {
   return frame_tree_node_->frame_tree_node_id();
 }
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h
index bd236a7..279c459 100644
--- a/content/browser/frame_host/navigation_handle_impl.h
+++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -97,6 +97,7 @@
   bool IsParentMainFrame() override;
   bool IsRendererInitiated() override;
   bool WasServerRedirect() override;
+  const std::vector<GURL>& GetRedirectChain() override;
   int GetFrameTreeNodeId() override;
   int GetParentFrameTreeNodeId() override;
   const base::TimeTicks& NavigationStart() override;
diff --git a/content/browser/loader/mojo_async_resource_handler.cc b/content/browser/loader/mojo_async_resource_handler.cc
index c2070cd..826db44 100644
--- a/content/browser/loader/mojo_async_resource_handler.cc
+++ b/content/browser/loader/mojo_async_resource_handler.cc
@@ -121,6 +121,7 @@
     : ResourceHandler(request),
       rdh_(rdh),
       binding_(this, std::move(mojo_request)),
+      handle_watcher_(FROM_HERE),
       url_loader_client_(std::move(url_loader_client)),
       weak_factory_(this) {
   DCHECK(url_loader_client_);
diff --git a/content/browser/presentation/presentation_service_impl.cc b/content/browser/presentation/presentation_service_impl.cc
index 3da5b3b..2b6aca7 100644
--- a/content/browser/presentation/presentation_service_impl.cc
+++ b/content/browser/presentation/presentation_service_impl.cc
@@ -295,16 +295,15 @@
   return request_id;
 }
 
-void PresentationServiceImpl::ListenForConnectionStateChangeAndChangeState(
+void PresentationServiceImpl::ListenForConnectionStateChange(
     const PresentationSessionInfo& connection) {
+  // NOTE: Blink will automatically transition the connection's state to
+  // 'connected'.
   if (controller_delegate_) {
     controller_delegate_->ListenForConnectionStateChange(
         render_process_id_, render_frame_id_, connection,
         base::Bind(&PresentationServiceImpl::OnConnectionStateChanged,
                    weak_factory_.GetWeakPtr(), connection));
-    OnConnectionStateChanged(connection,
-                             PresentationConnectionStateChangeInfo(
-                                 PRESENTATION_CONNECTION_STATE_CONNECTED));
   }
 }
 
@@ -318,7 +317,7 @@
   pending_start_session_cb_->Run(
       blink::mojom::PresentationSessionInfo::From(session_info),
       blink::mojom::PresentationErrorPtr());
-  ListenForConnectionStateChangeAndChangeState(session_info);
+  ListenForConnectionStateChange(session_info);
   pending_start_session_cb_.reset();
   start_session_request_id_ = kInvalidRequestSessionId;
 }
@@ -343,7 +342,7 @@
           request_session_id,
           blink::mojom::PresentationSessionInfo::From(session_info),
           blink::mojom::PresentationErrorPtr())) {
-    ListenForConnectionStateChangeAndChangeState(session_info);
+    ListenForConnectionStateChange(session_info);
   }
 }
 
@@ -616,7 +615,7 @@
   DCHECK(client_.get());
   client_->OnDefaultSessionStarted(
       blink::mojom::PresentationSessionInfo::From(connection));
-  ListenForConnectionStateChangeAndChangeState(connection);
+  ListenForConnectionStateChange(connection);
 }
 
 PresentationServiceImpl::ScreenAvailabilityListenerImpl::
diff --git a/content/browser/presentation/presentation_service_impl.h b/content/browser/presentation/presentation_service_impl.h
index 0868dda..b4c3d85 100644
--- a/content/browser/presentation/presentation_service_impl.h
+++ b/content/browser/presentation/presentation_service_impl.h
@@ -92,7 +92,7 @@
   FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
                            MaxPendingJoinSessionRequests);
   FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
-                           ListenForConnectionStateChangeAndChangeState);
+                           ListenForConnectionStateChange);
   FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
                            ListenForConnectionClose);
   FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
@@ -237,9 +237,8 @@
   void OnSendMessageCallback(bool sent);
 
   // Calls to |delegate_| to start listening for state changes for |connection|.
-  // State changes will be returned via |OnConnectionStateChanged|. Change
-  // |connection|'s state to 'connected' after listening.
-  void ListenForConnectionStateChangeAndChangeState(
+  // State changes will be returned via |OnConnectionStateChanged|.
+  void ListenForConnectionStateChange(
       const PresentationSessionInfo& connection);
 
   // Passed to embedder's implementation of PresentationServiceDelegate for
diff --git a/content/browser/presentation/presentation_service_impl_unittest.cc b/content/browser/presentation/presentation_service_impl_unittest.cc
index e0028b7..79d9f635 100644
--- a/content/browser/presentation/presentation_service_impl_unittest.cc
+++ b/content/browser/presentation/presentation_service_impl_unittest.cc
@@ -544,7 +544,7 @@
 }
 
 TEST_F(PresentationServiceImplTest,
-       ListenForConnectionStateChangeAndChangeState) {
+       ListenForConnectionStateChange) {
   content::PresentationSessionInfo connection(presentation_url1_,
                                               kPresentationId);
   content::PresentationConnectionStateChangedCallback state_changed_cb;
@@ -555,11 +555,7 @@
 
   EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _))
       .WillOnce(SaveArg<3>(&state_changed_cb));
-  EXPECT_CALL(mock_client_,
-              OnConnectionStateChanged(
-                  SessionInfoEquals(ByRef(presentation_connection)),
-                  blink::mojom::PresentationConnectionState::CONNECTED));
-  service_impl_->ListenForConnectionStateChangeAndChangeState(connection);
+  service_impl_->ListenForConnectionStateChange(connection);
 
   {
     base::RunLoop run_loop;
@@ -580,7 +576,7 @@
   content::PresentationConnectionStateChangedCallback state_changed_cb;
   EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _))
       .WillOnce(SaveArg<3>(&state_changed_cb));
-  service_impl_->ListenForConnectionStateChangeAndChangeState(connection);
+  service_impl_->ListenForConnectionStateChange(connection);
 
   // Trigger connection close. It should be propagated back up to
   // |mock_client_|.
diff --git a/content/browser/renderer_host/OWNERS b/content/browser/renderer_host/OWNERS
index f01281f..7b344e67 100644
--- a/content/browser/renderer_host/OWNERS
+++ b/content/browser/renderer_host/OWNERS
@@ -33,3 +33,5 @@
 per-file offscreen_canvas*.*=xlai@chromium.org
 per-file offscreen_canvas*.*=xidachen@chromium.org
 per-file offscreen_canvas*.*=junov@chromium.org
+
+# COMPONENT: Internals>Core
diff --git a/content/browser/web_contents/web_contents_view_guest.cc b/content/browser/web_contents/web_contents_view_guest.cc
index b2b86fa..a93bc37 100644
--- a/content/browser/web_contents/web_contents_view_guest.cc
+++ b/content/browser/web_contents/web_contents_view_guest.cc
@@ -92,7 +92,8 @@
   if (guest_->embedder_web_contents()) {
     // We need embedder container's bounds to calculate our bounds.
     guest_->embedder_web_contents()->GetView()->GetContainerBounds(out);
-    gfx::Point guest_coordinates = guest_->GetScreenCoordinates(gfx::Point());
+    gfx::Point guest_coordinates =
+        guest_->GetCoordinatesInEmbedderWebContents(gfx::Point());
     out->Offset(guest_coordinates.x(), guest_coordinates.y());
   } else {
     out->set_origin(gfx::Point());
diff --git a/content/child/request_extra_data.cc b/content/child/request_extra_data.cc
index 2d26828..afde2df 100644
--- a/content/child/request_extra_data.cc
+++ b/content/child/request_extra_data.cc
@@ -28,7 +28,8 @@
       initiated_in_secure_context_(false),
       is_prefetch_(false),
       download_to_network_cache_only_(false),
-      block_mixed_plugin_content_(false) {}
+      block_mixed_plugin_content_(false),
+      navigation_initiated_by_renderer_(false) {}
 
 RequestExtraData::~RequestExtraData() {
 }
diff --git a/content/child/request_extra_data.h b/content/child/request_extra_data.h
index d544989..730af14 100644
--- a/content/child/request_extra_data.h
+++ b/content/child/request_extra_data.h
@@ -158,6 +158,15 @@
     block_mixed_plugin_content_ = block_mixed_plugin_content;
   }
 
+  // PlzNavigate
+  // Indicates whether a navigation was initiated by the browser or renderer.
+  bool navigation_initiated_by_renderer() const {
+    return navigation_initiated_by_renderer_;
+  }
+  void set_navigation_initiated_by_renderer(bool navigation_by_renderer) {
+    navigation_initiated_by_renderer_ = navigation_by_renderer;
+  }
+
   void CopyToResourceRequest(ResourceRequest* request) const;
 
  private:
@@ -181,6 +190,7 @@
   bool is_prefetch_;
   bool download_to_network_cache_only_;
   bool block_mixed_plugin_content_;
+  bool navigation_initiated_by_renderer_;
 
   DISALLOW_COPY_AND_ASSIGN(RequestExtraData);
 };
diff --git a/content/child/url_response_body_consumer.cc b/content/child/url_response_body_consumer.cc
index cb89be51..a51b4f7 100644
--- a/content/child/url_response_body_consumer.cc
+++ b/content/child/url_response_body_consumer.cc
@@ -48,7 +48,7 @@
     : request_id_(request_id),
       resource_dispatcher_(resource_dispatcher),
       handle_(std::move(handle)),
-      handle_watcher_(task_runner),
+      handle_watcher_(FROM_HERE, task_runner),
       task_runner_(task_runner),
       has_seen_end_of_data_(!handle_.is_valid()) {
   handle_watcher_.Start(
diff --git a/content/child/web_data_consumer_handle_impl.cc b/content/child/web_data_consumer_handle_impl.cc
index fdec9c9..f81221d8 100644
--- a/content/child/web_data_consumer_handle_impl.cc
+++ b/content/child/web_data_consumer_handle_impl.cc
@@ -37,7 +37,7 @@
 WebDataConsumerHandleImpl::ReaderImpl::ReaderImpl(
     scoped_refptr<Context> context,
     Client* client)
-    : context_(context), client_(client) {
+    : context_(context), handle_watcher_(FROM_HERE), client_(client) {
   if (client_)
     StartWatching();
 }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionImpl.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionImpl.java
index 23534fe..4e56218 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionImpl.java
@@ -42,6 +42,9 @@
     // into the class are synchronized on the lock to protect access to these members.
     private final Object mLock = new Object();
     private IChildProcessService mService;
+    // Set to true when the service connection callback runs. This differs from
+    // mServiceConnectComplete, which tracks that the connection completed successfully.
+    private boolean mDidOnServiceConnected;
     // Set to true when the service connected successfully.
     private boolean mServiceConnectComplete;
     // Set to true when the service disconnects, as opposed to being properly closed. This happens
@@ -163,13 +166,13 @@
             synchronized (mLock) {
                 // A flag from the parent class ensures we run the post-connection logic only once
                 // (instead of once per each ChildServiceConnection).
-                if (mServiceConnectComplete) {
+                if (mDidOnServiceConnected) {
                     return;
                 }
                 try {
                     TraceEvent.begin(
                             "ChildProcessConnectionImpl.ChildServiceConnection.onServiceConnected");
-                    mServiceConnectComplete = true;
+                    mDidOnServiceConnected = true;
                     mService = IChildProcessService.Stub.asInterface(service);
 
                     boolean boundToUs = false;
@@ -191,6 +194,8 @@
                         return;
                     }
 
+                    mServiceConnectComplete = true;
+
                     // Run the setup if the connection parameters have already been provided. If
                     // not, doConnectionSetupLocked() will be called from setupConnection().
                     if (mConnectionParams != null) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java
index 3ae8def..9b7d6b2 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java
@@ -133,6 +133,11 @@
         int allocatedConnectionsCountForTesting() {
             return mChildProcessConnections.length - mFreeConnectionIndices.size();
         }
+
+        @VisibleForTesting
+        ChildProcessConnection[] connectionArrayForTesting() {
+            return mChildProcessConnections;
+        }
     }
 
     private static class PendingSpawnData {
@@ -946,11 +951,12 @@
     }
 
     /**
-     * @return the service map of connected services
+     * @return gets the service connection array for a specific package name.
      */
     @VisibleForTesting
-    static Map<Integer, ChildProcessConnection> getServiceMapForTesting() {
-        return sServiceMap;
+    static ChildProcessConnection[] getSandboxedConnectionArrayForTesting(
+            String packageName) {
+        return sSandboxedChildConnectionAllocatorMap.get(packageName).connectionArrayForTesting();
     }
 
     /** @return the count of services set up and working */
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java
index 5f1a34b..2b782cf 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java
@@ -27,7 +27,6 @@
 import org.chromium.content.common.FileDescriptorInfo;
 import org.chromium.content_shell_apk.ChildProcessLauncherTestHelperService;
 
-import java.util.Map;
 import java.util.concurrent.Callable;
 
 /**
@@ -399,50 +398,50 @@
                     }
                 });
 
-        triggerConnectionSetup((ChildProcessConnectionImpl) conn);
-
         assertEquals(0, conn.getServiceNumber());
-        assertEquals(-1, conn.getPid());  // PID gets set to -1 if service is already bound.
 
-        final Map<Integer, ChildProcessConnection> serviceMap =
-                ChildProcessLauncher.getServiceMapForTesting();
+        final ChildProcessConnection[] sandboxedConnections =
+                ChildProcessLauncher.getSandboxedConnectionArrayForTesting(
+                        context.getPackageName());
 
         // Wait for the retry to succeed.
         CriteriaHelper.pollInstrumentationThread(
                 new Criteria("Failed waiting for both child process services") {
                     @Override
                     public boolean isSatisfied() {
-                        boolean allChildrenConnected = serviceMap.size() == 2;
-                        for (ChildProcessConnection conn : serviceMap.values()) {
-                            allChildrenConnected &= conn.getService() != null;
+                        boolean allChildrenConnected = true;
+                        for (int i = 0; i <= 1; ++i) {
+                            ChildProcessConnection conn = sandboxedConnections[i];
+                            allChildrenConnected &= conn != null && conn.getService() != null;
                         }
                         return allChildrenConnected;
                     }
                 });
 
-        assertEquals(2, serviceMap.size());
-
-        boolean testedSlot0 = false, testedSlot1 = false;
-
-        for (ChildProcessConnection childProcess : serviceMap.values()) {
-            if (childProcess == conn) {
-                assertFalse(testedSlot0);
-                assertEquals(0, childProcess.getServiceNumber());
-                assertEquals(-1, childProcess.getPid());
-                assertFalse(childProcess.getService().bindToCaller());
-                testedSlot0 = true;
+        // Check that only two connections are created.
+        for (int i = 0; i < sandboxedConnections.length; ++i) {
+            ChildProcessConnection sandboxedConn = sandboxedConnections[i];
+            if (i <= 1) {
+                assertNotNull(sandboxedConn);
+                assertNotNull(sandboxedConn.getService());
             } else {
-                assertFalse(testedSlot1);
-                assertEquals(1, childProcess.getServiceNumber());
-                assertTrue(childProcess.getPid() > 0);
-                assertTrue(childProcess.getPid() != helperConnPid);
-                assertTrue(childProcess.getService().bindToCaller());
-                testedSlot1 = true;
+                assertNull(sandboxedConn);
             }
         }
 
-        assertTrue(testedSlot0);
-        assertTrue(testedSlot1);
+        assertTrue(conn == sandboxedConnections[0]);
+        final ChildProcessConnection retryConn = sandboxedConnections[1];
+
+        assertFalse(conn == retryConn);
+
+        assertEquals(0, conn.getServiceNumber());
+        assertEquals(0, conn.getPid());
+        assertFalse(conn.getService().bindToCaller());
+
+        assertEquals(1, retryConn.getServiceNumber());
+        assertTrue(retryConn.getPid() > 0);
+        assertTrue(retryConn.getPid() != helperConnPid);
+        assertTrue(retryConn.getService().bindToCaller());
     }
 
     private ChildProcessConnectionImpl startConnection() {
diff --git a/content/public/browser/navigation_handle.h b/content/public/browser/navigation_handle.h
index 59114df5..153be328 100644
--- a/content/public/browser/navigation_handle.h
+++ b/content/public/browser/navigation_handle.h
@@ -160,6 +160,11 @@
   // Whether the navigation has encountered a server redirect or not.
   virtual bool WasServerRedirect() = 0;
 
+  // Lists the redirects that occurred on the way to the current page. The
+  // current page is the last one in the list (so even when there's no redirect,
+  // there will be one entry in the list).
+  virtual const std::vector<GURL>& GetRedirectChain() = 0;
+
   // Whether the navigation has committed. This returns true for either
   // successful commits or error pages that replace the previous page
   // (distinguished by |IsErrorPage|), and false for errors that leave the user
diff --git a/content/public/test/layouttest_support.h b/content/public/test/layouttest_support.h
index 074270b..f23eafb 100644
--- a/content/public/test/layouttest_support.h
+++ b/content/public/test/layouttest_support.h
@@ -23,6 +23,7 @@
 class WebInputEvent;
 class WebLocalFrame;
 struct WebSize;
+class WebURLRequest;
 class WebView;
 class WebWidget;
 class WebURLResponse;
@@ -176,6 +177,11 @@
 // TextInputState.
 void ForceTextInputStateUpdateForRenderFrame(RenderFrame* render_frame);
 
+// PlzNavigate
+// Returns true if the navigation identified by the |request| was initiated by
+// the browser or renderer.
+bool IsNavigationInitiatedByRenderer(const blink::WebURLRequest& request);
+
 }  // namespace content
 
 #endif  // CONTENT_PUBLIC_TEST_LAYOUTTEST_SUPPORT_H_
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc
index 748eb78..2c9c1f87 100644
--- a/content/renderer/browser_plugin/browser_plugin.cc
+++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -389,9 +389,13 @@
   gfx::Rect old_view_rect = view_rect_;
   // Convert the plugin_rect_in_viewport to window coordinates, which is css.
   WebRect rect_in_css(plugin_rect_in_viewport);
-  blink::WebView* webview = container()->document().frame()->view();
-  RenderViewImpl::FromWebView(webview)->GetWidget()->convertViewportToWindow(
-      &rect_in_css);
+
+  // We will use the local root's RenderWidget to convert coordinates to Window.
+  // If this local root belongs to an OOPIF, on the browser side we will have to
+  // consider the displacement of the child frame in root window.
+  RenderFrameImpl::FromWebFrame(container()->document().frame())
+      ->GetRenderWidget()
+      ->convertViewportToWindow(&rect_in_css);
   view_rect_ = rect_in_css;
 
   if (!ready_) {
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index eb5dfd4..f30efe8 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -556,7 +556,8 @@
 WebURLRequest CreateURLRequestForNavigation(
     const CommonNavigationParams& common_params,
     std::unique_ptr<StreamOverrideParameters> stream_override,
-    bool is_view_source_mode_enabled) {
+    bool is_view_source_mode_enabled,
+    int nav_entry_id) {
   WebURLRequest request(common_params.url);
   if (is_view_source_mode_enabled)
     request.setCachePolicy(WebCachePolicy::ReturnCacheDataElseLoad);
@@ -579,6 +580,7 @@
 
   RequestExtraData* extra_data = new RequestExtraData();
   extra_data->set_stream_override(std::move(stream_override));
+  extra_data->set_navigation_initiated_by_renderer(nav_entry_id == 0);
   request.setExtraData(extra_data);
 
   // Set the ui timestamp for this navigation. Currently the timestamp here is
@@ -4335,6 +4337,16 @@
         navigation_state->start_params().transferred_request_child_id);
     extra_data->set_transferred_request_request_id(
         navigation_state->start_params().transferred_request_request_id);
+
+    // For navigation requests, we should copy the flag which indicates if this
+    // was a navigation initiated by the renderer to the new RequestExtraData
+    // instance.
+    RequestExtraData* current_request_data = static_cast<RequestExtraData*>(
+      request.getExtraData());
+    if (current_request_data) {
+      extra_data->set_navigation_initiated_by_renderer(
+          current_request_data->navigation_initiated_by_renderer());
+    }
   }
 
   request.setExtraData(extra_data);
@@ -5172,7 +5184,7 @@
       CreateWebURLError(common_params.url, has_stale_copy_in_cache, error_code);
   WebURLRequest failed_request = CreateURLRequestForNavigation(
       common_params, std::unique_ptr<StreamOverrideParameters>(),
-      frame_->isViewSourceModeEnabled());
+      frame_->isViewSourceModeEnabled(), request_params.nav_entry_id);
 
   if (!ShouldDisplayErrorPageForFailedLoad(error_code, common_params.url)) {
     // The browser expects this frame to be loading an error page. Inform it
@@ -5846,7 +5858,8 @@
   WebHistoryItem item_for_history_navigation;
   WebURLRequest request =
       CreateURLRequestForNavigation(common_params, std::move(stream_params),
-                                    frame_->isViewSourceModeEnabled());
+                                    frame_->isViewSourceModeEnabled(),
+                                    request_params.nav_entry_id);
   request.setFrameType(IsTopLevelNavigation(frame_)
                            ? blink::WebURLRequest::FrameTypeTopLevel
                            : blink::WebURLRequest::FrameTypeNested);
diff --git a/content/shell/browser/shell_devtools_frontend.cc b/content/shell/browser/shell_devtools_frontend.cc
index af9789d..ac02b03 100644
--- a/content/shell/browser/shell_devtools_frontend.cc
+++ b/content/shell/browser/shell_devtools_frontend.cc
@@ -284,6 +284,9 @@
   } else if (method == "requestFileSystems") {
     web_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
         base::ASCIIToUTF16("DevToolsAPI.fileSystemsLoaded([]);"));
+  } else if (method == "reattach") {
+    agent_host_->DetachClient(this);
+    agent_host_->AttachClient(this);
   } else {
     return;
   }
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc
index 881cfb7..aeccd01d 100644
--- a/content/shell/renderer/layout_test/blink_test_runner.cc
+++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -747,6 +747,11 @@
   ForceTextInputStateUpdateForRenderFrame(RenderFrame::FromWebFrame(frame));
 }
 
+bool BlinkTestRunner::IsNavigationInitiatedByRenderer(
+    const WebURLRequest& request) {
+  return content::IsNavigationInitiatedByRenderer(request);
+}
+
 bool BlinkTestRunner::AddMediaStreamVideoSourceAndTrack(
     blink::WebMediaStream* stream) {
   DCHECK(stream);
diff --git a/content/shell/renderer/layout_test/blink_test_runner.h b/content/shell/renderer/layout_test/blink_test_runner.h
index 4d69a11e..62d7422 100644
--- a/content/shell/renderer/layout_test/blink_test_runner.h
+++ b/content/shell/renderer/layout_test/blink_test_runner.h
@@ -31,6 +31,7 @@
 class WebDeviceMotionData;
 class WebDeviceOrientationData;
 class WebFrame;
+class WebURLRequest;
 class WebView;
 }
 
@@ -162,6 +163,8 @@
   float GetDeviceScaleFactor() const override;
   void RunIdleTasks(const base::Closure& callback) override;
   void ForceTextInputStateUpdate(blink::WebFrame* frame) override;
+  bool IsNavigationInitiatedByRenderer(
+      const blink::WebURLRequest& request) override;
 
   // Resets a RenderView to a known state for layout tests. It is used both when
   // a RenderView is created and when reusing an existing RenderView for the
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
index fcb0434..a143953 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -352,7 +352,7 @@
     self.Fail('conformance/textures/misc/' +
         'copytexsubimage2d-large-partial-copy-corruption.html',
         ['win', 'intel', 'passthrough', 'd3d11'], bug=602688)
-    self.Flaky('conformance/textures/misc/copytexsubimage2d-subrects.html',
+    self.Fail('conformance/textures/misc/copytexsubimage2d-subrects.html',
         ['win10', 'intel', 'passthrough', 'd3d11'], bug=685232)
 
     # Mac failures
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc
index 784fb2c..8f7c7722 100644
--- a/content/test/layouttest_support.cc
+++ b/content/test/layouttest_support.cc
@@ -23,6 +23,7 @@
 #include "content/browser/bluetooth/bluetooth_device_chooser_controller.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/child/request_extra_data.h"
 #include "content/common/renderer.mojom.h"
 #include "content/public/common/page_state.h"
 #include "content/public/common/screen_info.h"
@@ -604,4 +605,10 @@
   }
 }
 
+bool IsNavigationInitiatedByRenderer(const blink::WebURLRequest& request) {
+  RequestExtraData* extra_data = static_cast<RequestExtraData*>(
+      request.getExtraData());
+  return extra_data && extra_data->navigation_initiated_by_renderer();
+}
+
 }  // namespace content
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index 71f9322..79abf33 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -963,6 +963,12 @@
       <message name="IDS_IOS_PAYMENT_REQUEST_SHIPPING_ADDRESS_SELECTION_TITLE" desc="Title of the view that allows the user to select the shipping address for satisfying a payment request [iOS only].">
         Shipping Address
       </message>
+      <message name="IDS_IOS_PAYMENT_REQUEST_SHIPPING_ADDRESS_SELECTION_MESSAGE" desc="Message instructing the user to select a shipping address for satisfying a payment request [iOS only].">
+        Select a shipping address to check shipping methods and requirements.
+      </message>
+      <message name="IDS_IOS_PAYMENT_REQUEST_CHECKING_LABEL" desc="Label showing that the new shipping address or the shipping option is being verified. [iOS only]">
+        Checking
+      </message>
       <message name="IDS_IOS_PAYMENT_REQUEST_SHIPPING_OPTION_SELECTION_TITLE" desc="Title of the view that allows the user to select the shipping option for satisfying a payment request [iOS only].">
         Shipping Method
       </message>
diff --git a/ios/chrome/app/theme/default_100_percent/payments_add.png b/ios/chrome/app/theme/default_100_percent/payments_add.png
new file mode 100644
index 0000000..0d533fce
--- /dev/null
+++ b/ios/chrome/app/theme/default_100_percent/payments_add.png
Binary files differ
diff --git a/ios/chrome/app/theme/default_100_percent/payments_warning.png b/ios/chrome/app/theme/default_100_percent/payments_warning.png
new file mode 100644
index 0000000..f0b6f76
--- /dev/null
+++ b/ios/chrome/app/theme/default_100_percent/payments_warning.png
Binary files differ
diff --git a/ios/chrome/app/theme/default_200_percent/payments_add.png b/ios/chrome/app/theme/default_200_percent/payments_add.png
new file mode 100644
index 0000000..6fdc28d
--- /dev/null
+++ b/ios/chrome/app/theme/default_200_percent/payments_add.png
Binary files differ
diff --git a/ios/chrome/app/theme/default_200_percent/payments_warning.png b/ios/chrome/app/theme/default_200_percent/payments_warning.png
new file mode 100644
index 0000000..704a25a
--- /dev/null
+++ b/ios/chrome/app/theme/default_200_percent/payments_warning.png
Binary files differ
diff --git a/ios/chrome/app/theme/default_300_percent/payments_add.png b/ios/chrome/app/theme/default_300_percent/payments_add.png
new file mode 100644
index 0000000..187ebc3
--- /dev/null
+++ b/ios/chrome/app/theme/default_300_percent/payments_add.png
Binary files differ
diff --git a/ios/chrome/app/theme/default_300_percent/payments_warning.png b/ios/chrome/app/theme/default_300_percent/payments_warning.png
new file mode 100644
index 0000000..ba4929a
--- /dev/null
+++ b/ios/chrome/app/theme/default_300_percent/payments_warning.png
Binary files differ
diff --git a/ios/chrome/app/theme/ios_theme_resources.grd b/ios/chrome/app/theme/ios_theme_resources.grd
index cf33d86..4ff5648 100644
--- a/ios/chrome/app/theme/ios_theme_resources.grd
+++ b/ios/chrome/app/theme/ios_theme_resources.grd
@@ -66,6 +66,8 @@
       <structure type="chrome_scaled_image" name="IDR_IOS_PAGEINFO_BAD" file="omnibox/pageinfo_bad.png" />
       <structure type="chrome_scaled_image" name="IDR_IOS_PAGEINFO_GOOD" file="omnibox/pageinfo_good.png" />
       <structure type="chrome_scaled_image" name="IDR_IOS_PAGEINFO_INFO" file="omnibox/pageinfo_info.png" />
+      <structure type="chrome_scaled_image" name="IDR_IOS_PAYMENTS_ADD" file="payments_add.png" />
+      <structure type="chrome_scaled_image" name="IDR_IOS_PAYMENTS_WARNING" file="payments_warning.png" />
       <structure type="chrome_scaled_image" name="IDR_IOS_PROMO_INFO" file="promo_info.png" />
       <structure type="chrome_scaled_image" name="IDR_IOS_SETTINGS_INFO_24" file="settings_info_24.png" />
       <structure type="chrome_scaled_image" name="IDR_IOS_TOOLBAR_DARK_BACK" file="toolbar_dark_back.png" />
diff --git a/ios/chrome/browser/payments/BUILD.gn b/ios/chrome/browser/payments/BUILD.gn
index 19ebe31..3daf89d 100644
--- a/ios/chrome/browser/payments/BUILD.gn
+++ b/ios/chrome/browser/payments/BUILD.gn
@@ -45,11 +45,13 @@
     "//components/autofill/core/browser",
     "//components/strings",
     "//ios/chrome/app/strings",
+    "//ios/chrome/app/theme",
     "//ios/chrome/browser",
     "//ios/chrome/browser/autofill",
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/payments/cells",
     "//ios/chrome/browser/ui",
+    "//ios/chrome/browser/ui/autofill/cells",
     "//ios/chrome/browser/ui/collection_view",
     "//ios/chrome/browser/ui/collection_view/cells",
     "//ios/chrome/browser/ui/colors",
@@ -67,6 +69,7 @@
   sources = [
     "payment_items_display_coordinator_unittest.mm",
     "payment_items_display_view_controller_unittest.mm",
+    "payment_method_selection_view_controller_unittest.mm",
     "shipping_address_selection_coordinator_unittest.mm",
     "shipping_address_selection_view_controller_unittest.mm",
     "shipping_option_selection_coordinator_unittest.mm",
@@ -78,6 +81,8 @@
     "//base/test:test_support",
     "//components/autofill/core/browser",
     "//ios/chrome/app/strings",
+    "//ios/chrome/browser/payments/cells",
+    "//ios/chrome/browser/ui/autofill/cells",
     "//ios/chrome/browser/ui/collection_view:test_support",
     "//ios/chrome/browser/ui/collection_view/cells",
     "//ios/chrome/browser/ui/collection_view/cells:test_support",
diff --git a/ios/chrome/browser/payments/cells/BUILD.gn b/ios/chrome/browser/payments/cells/BUILD.gn
index 9f46adc..bb65368 100644
--- a/ios/chrome/browser/payments/cells/BUILD.gn
+++ b/ios/chrome/browser/payments/cells/BUILD.gn
@@ -8,12 +8,17 @@
     "page_info_item.mm",
     "payment_method_item.h",
     "payment_method_item.mm",
+    "payments_text_item.h",
+    "payments_text_item.mm",
+    "price_item.h",
+    "price_item.mm",
     "shipping_address_item.h",
     "shipping_address_item.mm",
   ]
 
   deps = [
     "//ios/chrome/browser/ui/collection_view/cells",
+    "//ios/chrome/browser/ui/colors",
     "//ios/third_party/material_components_ios",
     "//ios/third_party/material_roboto_font_loader_ios",
   ]
@@ -26,6 +31,8 @@
   sources = [
     "page_info_item_unittest.mm",
     "payment_method_item_unittest.mm",
+    "payments_text_item_unittest.mm",
+    "price_item_unittest.mm",
     "shipping_address_item_unittest.mm",
   ]
 
diff --git a/ios/chrome/browser/payments/cells/page_info_item.mm b/ios/chrome/browser/payments/cells/page_info_item.mm
index ffdde5ba..d052709 100644
--- a/ios/chrome/browser/payments/cells/page_info_item.mm
+++ b/ios/chrome/browser/payments/cells/page_info_item.mm
@@ -28,6 +28,8 @@
 @synthesize pageTitle = _pageTitle;
 @synthesize pageHost = _pageHost;
 
+#pragma mark CollectionViewItem
+
 - (instancetype)initWithType:(NSInteger)type {
   self = [super initWithType:type];
   if (self) {
@@ -36,8 +38,6 @@
   return self;
 }
 
-#pragma mark CollectionViewItem
-
 - (void)configureCell:(PageInfoCell*)cell {
   [super configureCell:cell];
   cell.pageFaviconView.image = self.pageFavicon;
diff --git a/ios/chrome/browser/payments/cells/payments_text_item.h b/ios/chrome/browser/payments/cells/payments_text_item.h
new file mode 100644
index 0000000..ab3c143
--- /dev/null
+++ b/ios/chrome/browser/payments/cells/payments_text_item.h
@@ -0,0 +1,41 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_PAYMENTS_CELLS_PAYMENTS_TEXT_ITEM_H_
+#define IOS_CHROME_BROWSER_PAYMENTS_CELLS_PAYMENTS_TEXT_ITEM_H_
+
+#import <UIKit/UIKit.h>
+
+#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
+#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
+
+// PaymentsTextItem is the model class corresponding to PaymentsTextCell.
+@interface PaymentsTextItem : CollectionViewItem
+
+// The message to display.
+@property(nonatomic, copy) NSString* text;
+
+// The image to display.
+@property(nonatomic, strong) UIImage* image;
+
+@end
+
+// PaymentsTextCell implements a MDCCollectionViewCell subclass containing
+// a text label and an optional image. The label is laid out to fill the full
+// width of the cell and is wrapped as needed to fit in the cell. The image is
+// laid out on the leading edge of the cell. The text label is laid out on the
+// the trailing edge of the image, if one exists, or the leading edge of the
+// cell otherwise, up to the trailing edge of the cell. This is suitable for
+// displaying text that needs to wrap which may or may not feature an image.
+@interface PaymentsTextCell : MDCCollectionViewCell
+
+// UILabel corresponding to |text| from the item.
+@property(nonatomic, readonly, strong) UILabel* textLabel;
+
+// UIImageView corresponding to |image| from the item.
+@property(nonatomic, readonly, strong) UIImageView* imageView;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_PAYMENTS_CELLS_PAYMENTS_TEXT_ITEM_H_
diff --git a/ios/chrome/browser/payments/cells/payments_text_item.mm b/ios/chrome/browser/payments/cells/payments_text_item.mm
new file mode 100644
index 0000000..274f93e
--- /dev/null
+++ b/ios/chrome/browser/payments/cells/payments_text_item.mm
@@ -0,0 +1,154 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/payments/cells/payments_text_item.h"
+
+#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
+#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+// Padding of the leading and trailing edges of the cell.
+const CGFloat kHorizontalPadding = 16;
+
+// Padding of the top and bottom edges of the cell.
+const CGFloat kVerticalPadding = 16;
+
+// Spacing between the image and the text label.
+const CGFloat kHorizontalSpacingBetweenImageAndLabel = 8;
+}  // namespace
+
+@implementation PaymentsTextItem
+
+@synthesize text = _text;
+@synthesize image = _image;
+
+#pragma mark CollectionViewItem
+
+- (instancetype)initWithType:(NSInteger)type {
+  self = [super initWithType:type];
+  if (self) {
+    self.cellClass = [PaymentsTextCell class];
+  }
+  return self;
+}
+
+- (void)configureCell:(PaymentsTextCell*)cell {
+  [super configureCell:cell];
+  cell.textLabel.text = self.text;
+  cell.imageView.image = self.image;
+}
+
+@end
+
+@interface PaymentsTextCell () {
+  NSLayoutConstraint* _textLeadingAnchorConstraint;
+  NSLayoutConstraint* _imageLeadingAnchorConstraint;
+}
+@end
+
+@implementation PaymentsTextCell
+
+@synthesize textLabel = _textLabel;
+@synthesize imageView = _imageView;
+
+- (instancetype)initWithFrame:(CGRect)frame {
+  self = [super initWithFrame:frame];
+  if (self) {
+    self.isAccessibilityElement = YES;
+    [self addSubviews];
+    [self setDefaultViewStyling];
+    [self setViewConstraints];
+  }
+  return self;
+}
+
+// Create and add subviews.
+- (void)addSubviews {
+  UIView* contentView = self.contentView;
+  contentView.clipsToBounds = YES;
+
+  _textLabel = [[UILabel alloc] init];
+  _textLabel.translatesAutoresizingMaskIntoConstraints = NO;
+  [contentView addSubview:_textLabel];
+
+  _imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
+  _imageView.translatesAutoresizingMaskIntoConstraints = NO;
+  [contentView addSubview:_imageView];
+}
+
+// Set default font and text colors for labels.
+- (void)setDefaultViewStyling {
+  _textLabel.font = [MDCTypography body1Font];
+  _textLabel.textColor = [[MDCPalette greyPalette] tint900];
+  _textLabel.numberOfLines = 0;
+  _textLabel.lineBreakMode = NSLineBreakByWordWrapping;
+}
+
+// Set constraints on subviews.
+- (void)setViewConstraints {
+  UIView* contentView = self.contentView;
+
+  _textLeadingAnchorConstraint = [_textLabel.leadingAnchor
+      constraintEqualToAnchor:_imageView.trailingAnchor];
+  _imageLeadingAnchorConstraint = [_imageView.leadingAnchor
+      constraintEqualToAnchor:contentView.leadingAnchor
+                     constant:kHorizontalPadding];
+
+  [NSLayoutConstraint activateConstraints:@[
+    [_textLabel.topAnchor constraintEqualToAnchor:self.contentView.topAnchor
+                                         constant:kVerticalPadding],
+    [_textLabel.bottomAnchor constraintEqualToAnchor:contentView.bottomAnchor
+                                            constant:-kVerticalPadding],
+    [_imageView.centerYAnchor
+        constraintEqualToAnchor:contentView.centerYAnchor],
+    _textLeadingAnchorConstraint,
+    _imageLeadingAnchorConstraint,
+  ]];
+}
+
+#pragma mark - UIView
+
+// Implement -layoutSubviews as per instructions in documentation for
+// +[MDCCollectionViewCell cr_preferredHeightForWidth:forItem:].
+- (void)layoutSubviews {
+  [super layoutSubviews];
+
+  // Adjust the text label preferredMaxLayoutWidth when the parent's width
+  // changes, for instance on screen rotation.
+  CGFloat parentWidth = CGRectGetWidth(self.contentView.frame);
+  if (_imageView.image) {
+    _textLabel.preferredMaxLayoutWidth =
+        parentWidth - (2 * kHorizontalPadding) -
+        kHorizontalSpacingBetweenImageAndLabel - _imageView.image.size.width;
+    _textLeadingAnchorConstraint.constant =
+        kHorizontalSpacingBetweenImageAndLabel;
+  } else {
+    _textLabel.preferredMaxLayoutWidth = parentWidth - (2 * kHorizontalPadding);
+    _textLeadingAnchorConstraint.constant = 0;
+  }
+
+  // Re-layout with the new preferred width to allow the label to adjust its
+  // height.
+  [super layoutSubviews];
+}
+
+#pragma mark - UICollectionReusableView
+
+- (void)prepareForReuse {
+  [super prepareForReuse];
+  self.textLabel.text = nil;
+  self.imageView.image = nil;
+}
+
+#pragma mark - NSObject(Accessibility)
+
+- (NSString*)accessibilityLabel {
+  return [NSString stringWithFormat:@"%@", self.textLabel.text];
+}
+
+@end
diff --git a/ios/chrome/browser/payments/cells/payments_text_item_unittest.mm b/ios/chrome/browser/payments/cells/payments_text_item_unittest.mm
new file mode 100644
index 0000000..1d1432f
--- /dev/null
+++ b/ios/chrome/browser/payments/cells/payments_text_item_unittest.mm
@@ -0,0 +1,40 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/payments/cells/payments_text_item.h"
+
+#import "ios/chrome/browser/ui/collection_view/cells/test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gtest_mac.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+
+// Tests that the text label and the image are set properly after a call to
+// |configureCell:|.
+TEST(PaymentsTextItemTest, TextLabelAndImage) {
+  PaymentsTextItem* item = [[PaymentsTextItem alloc] initWithType:0];
+
+  NSString* text = @"Lorem ipsum dolor sit amet";
+  UIImage* image = ios_internal::CollectionViewTestImage();
+
+  item.text = text;
+  item.image = image;
+
+  id cell = [[[item cellClass] alloc] init];
+  ASSERT_TRUE([cell isMemberOfClass:[PaymentsTextCell class]]);
+
+  PaymentsTextCell* paymentsTextCell = cell;
+  EXPECT_FALSE(paymentsTextCell.textLabel.text);
+  EXPECT_FALSE(paymentsTextCell.imageView.image);
+
+  [item configureCell:paymentsTextCell];
+  EXPECT_NSEQ(text, paymentsTextCell.textLabel.text);
+  EXPECT_NSEQ(image, paymentsTextCell.imageView.image);
+}
+
+}  // namespace
diff --git a/ios/chrome/browser/payments/cells/price_item.h b/ios/chrome/browser/payments/cells/price_item.h
new file mode 100644
index 0000000..ee8d71c
--- /dev/null
+++ b/ios/chrome/browser/payments/cells/price_item.h
@@ -0,0 +1,56 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_PAYMENTS_CELLS_PRICE_ITEM_H_
+#define IOS_CHROME_BROWSER_PAYMENTS_CELLS_PRICE_ITEM_H_
+
+#import <UIKit/UIKit.h>
+
+#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
+#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
+
+// PriceItem is the model class corresponding to PriceCell.
+@interface PriceItem : CollectionViewItem
+
+// The accessory type to display on the trailing edge of the cell.
+@property(nonatomic) MDCCollectionViewCellAccessoryType accessoryType;
+
+// The leading item string.
+@property(nonatomic, copy) NSString* item;
+
+// The middle notification string.
+@property(nonatomic, copy) NSString* notification;
+
+// The trailing price string.
+@property(nonatomic, copy) NSString* price;
+
+@end
+
+// PriceCell implements an MDCCollectionViewCell subclass containing three text
+// labels: an "item" label, a "notification" label, and a "price" label. Labels
+// are laid out side-by-side and fill the full width of the cell. If there is
+// sufficient room (after accounting for margins) for full widths of all the
+// labels, their full widths will be used. Otherwise, unless the price label
+// needs more than 50% of the available room, it won't get truncated. Then,
+// unless the notification label needs more than 50% of the remaining room, it
+// won't get truncated either. The item label then takes up the remaining room.
+@interface PriceCell : MDCCollectionViewCell
+
+// UILabels corresponding to |item|, |notification|, and |price| from the item.
+@property(nonatomic, readonly, strong) UILabel* itemLabel;
+@property(nonatomic, readonly, strong) UILabel* notificationLabel;
+@property(nonatomic, readonly, strong) UILabel* priceLabel;
+
+@end
+
+@interface PriceCell (TestingOnly)
+
+// Exposed for testing.
+@property(nonatomic, readonly) CGFloat itemLabelTargetWidth;
+@property(nonatomic, readonly) CGFloat notificationLabelTargetWidth;
+@property(nonatomic, readonly) CGFloat priceLabelTargetWidth;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_PAYMENTS_CELLS_PRICE_ITEM_H_
diff --git a/ios/chrome/browser/payments/cells/price_item.mm b/ios/chrome/browser/payments/cells/price_item.mm
new file mode 100644
index 0000000..eced2917
--- /dev/null
+++ b/ios/chrome/browser/payments/cells/price_item.mm
@@ -0,0 +1,247 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/payments/cells/price_item.h"
+
+#include <algorithm>
+
+#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
+#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+
+// Padding used on the leading and trailing edges of the cell and in between the
+// labels.
+const CGFloat kHorizontalPadding = 16;
+
+// Minimum proportion of the available width to guarantee to the labels.
+const CGFloat kMinWidthRatio = 0.5f;
+}
+
+@implementation PriceItem
+
+@synthesize accessoryType = _accessoryType;
+@synthesize item = _item;
+@synthesize notification = _notification;
+@synthesize price = _price;
+
+#pragma mark CollectionViewItem
+
+- (instancetype)initWithType:(NSInteger)type {
+  self = [super initWithType:type];
+  if (self) {
+    self.cellClass = [PriceCell class];
+  }
+  return self;
+}
+
+- (void)configureCell:(PriceCell*)cell {
+  [super configureCell:cell];
+  cell.accessoryType = self.accessoryType;
+  cell.itemLabel.text = self.item;
+  cell.notificationLabel.text = self.notification;
+  cell.priceLabel.text = self.price;
+}
+
+@end
+
+@implementation PriceCell {
+  NSLayoutConstraint* _itemLabelWidthConstraint;
+  NSLayoutConstraint* _notificationLabelWidthConstraint;
+  NSLayoutConstraint* _priceLabelWidthConstraint;
+}
+
+@synthesize itemLabel = _itemLabel;
+@synthesize notificationLabel = _notificationLabel;
+@synthesize priceLabel = _priceLabel;
+
+- (instancetype)initWithFrame:(CGRect)frame {
+  self = [super initWithFrame:frame];
+  if (self) {
+    self.isAccessibilityElement = YES;
+    [self addSubviews];
+    [self setDefaultViewStyling];
+    [self setViewConstraints];
+  }
+  return self;
+}
+
+// Create and add subviews.
+- (void)addSubviews {
+  UIView* contentView = self.contentView;
+  contentView.clipsToBounds = YES;
+
+  _itemLabel = [[UILabel alloc] init];
+  _itemLabel.translatesAutoresizingMaskIntoConstraints = NO;
+  [contentView addSubview:_itemLabel];
+
+  _notificationLabel = [[UILabel alloc] init];
+  _notificationLabel.translatesAutoresizingMaskIntoConstraints = NO;
+  [contentView addSubview:_notificationLabel];
+
+  _priceLabel = [[UILabel alloc] init];
+  _priceLabel.translatesAutoresizingMaskIntoConstraints = NO;
+  [contentView addSubview:_priceLabel];
+}
+
+// Set default font and text colors for labels.
+- (void)setDefaultViewStyling {
+  _itemLabel.font = [MDCTypography body2Font];
+  _itemLabel.textColor = [[MDCPalette greyPalette] tint900];
+
+  _notificationLabel.font = [MDCTypography body2Font];
+  _notificationLabel.textColor = [[MDCPalette greenPalette] tint800];
+
+  _priceLabel.font = [MDCTypography body1Font];
+  _priceLabel.textColor = [[MDCPalette greyPalette] tint900];
+}
+
+// Set constraints on subviews.
+- (void)setViewConstraints {
+  UIView* contentView = self.contentView;
+
+  _itemLabelWidthConstraint =
+      [_itemLabel.widthAnchor constraintEqualToConstant:0];
+  _notificationLabelWidthConstraint =
+      [_notificationLabel.widthAnchor constraintEqualToConstant:0];
+  _priceLabelWidthConstraint =
+      [_priceLabel.widthAnchor constraintEqualToConstant:0];
+
+  [NSLayoutConstraint activateConstraints:@[
+    // Fix the leading and trailing edges of the labels.
+    [_itemLabel.leadingAnchor constraintEqualToAnchor:contentView.leadingAnchor
+                                             constant:kHorizontalPadding],
+    [_notificationLabel.trailingAnchor
+        constraintEqualToAnchor:_priceLabel.leadingAnchor
+                       constant:-kHorizontalPadding],
+    [_priceLabel.trailingAnchor
+        constraintEqualToAnchor:contentView.trailingAnchor
+                       constant:-kHorizontalPadding],
+
+    // Center the item label vertically and align the baselines of the other two
+    // labels with the item label.
+    [_itemLabel.centerYAnchor
+        constraintEqualToAnchor:contentView.centerYAnchor],
+    [_notificationLabel.firstBaselineAnchor
+        constraintEqualToAnchor:_itemLabel.firstBaselineAnchor],
+    [_priceLabel.firstBaselineAnchor
+        constraintEqualToAnchor:_itemLabel.firstBaselineAnchor],
+
+    _itemLabelWidthConstraint,
+    _notificationLabelWidthConstraint,
+    _priceLabelWidthConstraint,
+  ]];
+}
+
+#pragma mark - UIView
+
+// Updates the width constraints of the text labels and then calls the
+// superclass's implementation of layoutSubviews which will then take the new
+// constraints into account.
+- (void)layoutSubviews {
+  [super layoutSubviews];
+
+  // Size the labels in order to determine how much width they want.
+  [self.itemLabel sizeToFit];
+  [self.notificationLabel sizeToFit];
+  [self.priceLabel sizeToFit];
+
+  // Update the width constraint of the labels.
+  _priceLabelWidthConstraint.constant = self.priceLabelTargetWidth;
+  _itemLabelWidthConstraint.constant = self.itemLabelTargetWidth;
+  _notificationLabelWidthConstraint.constant =
+      self.notificationLabelTargetWidth;
+
+  // Now invoke the layout.
+  [super layoutSubviews];
+}
+
+#pragma mark - UICollectionReusableView
+
+- (void)prepareForReuse {
+  [super prepareForReuse];
+  self.accessoryType = MDCCollectionViewCellAccessoryNone;
+  self.itemLabel.text = nil;
+  self.notificationLabel.text = nil;
+  self.priceLabel.text = nil;
+}
+
+#pragma mark - NSObject(Accessibility)
+
+- (NSString*)accessibilityLabel {
+  return [NSString stringWithFormat:@"%@, %@, %@", self.itemLabel.text,
+                                    self.notificationLabel.text,
+                                    self.priceLabel.text];
+}
+
+@end
+
+@implementation PriceCell (TestingOnly)
+
+- (CGFloat)itemLabelTargetWidth {
+  CGFloat itemLabelWidth = self.itemLabel.frame.size.width;
+  CGFloat notificationLabelWidth = self.notificationLabel.frame.size.width;
+  CGFloat priceLabelWidth = self.priceLabel.frame.size.width;
+
+  CGFloat horizontalPadding = (notificationLabelWidth > 0)
+                                  ? 4 * kHorizontalPadding
+                                  : 3 * kHorizontalPadding;
+  CGFloat availableWidth = CGRectGetWidth(self.contentView.frame) -
+                           self.priceLabelTargetWidth - horizontalPadding;
+
+  if (itemLabelWidth + notificationLabelWidth + priceLabelWidth <=
+      availableWidth) {
+    return itemLabelWidth;
+  } else {
+    return std::max(availableWidth - notificationLabelWidth,
+                    std::min(availableWidth * kMinWidthRatio, itemLabelWidth));
+  }
+}
+
+- (CGFloat)notificationLabelTargetWidth {
+  CGFloat itemLabelWidth = self.itemLabel.frame.size.width;
+  CGFloat notificationLabelWidth = self.notificationLabel.frame.size.width;
+  CGFloat priceLabelWidth = self.priceLabel.frame.size.width;
+
+  CGFloat horizontalPadding = (notificationLabelWidth > 0)
+                                  ? 4 * kHorizontalPadding
+                                  : 3 * kHorizontalPadding;
+  CGFloat availableWidth = CGRectGetWidth(self.contentView.frame) -
+                           self.priceLabelTargetWidth - horizontalPadding;
+
+  if (itemLabelWidth + notificationLabelWidth + priceLabelWidth <=
+      availableWidth) {
+    return notificationLabelWidth;
+  } else {
+    return std::max(
+        availableWidth - itemLabelWidth,
+        std::min(availableWidth * kMinWidthRatio, notificationLabelWidth));
+  }
+}
+
+- (CGFloat)priceLabelTargetWidth {
+  CGFloat itemLabelWidth = self.itemLabel.frame.size.width;
+  CGFloat notificationLabelWidth = self.notificationLabel.frame.size.width;
+  CGFloat priceLabelWidth = self.priceLabel.frame.size.width;
+
+  CGFloat horizontalPadding = (notificationLabelWidth > 0)
+                                  ? 4 * kHorizontalPadding
+                                  : 3 * kHorizontalPadding;
+  CGFloat availableWidth =
+      CGRectGetWidth(self.contentView.frame) - horizontalPadding;
+
+  if (itemLabelWidth + notificationLabelWidth + priceLabelWidth <=
+      availableWidth) {
+    return priceLabelWidth;
+  } else {
+    return std::max(availableWidth - itemLabelWidth - notificationLabelWidth,
+                    std::min(availableWidth * kMinWidthRatio, priceLabelWidth));
+  }
+}
+
+@end
diff --git a/ios/chrome/browser/payments/cells/price_item_unittest.mm b/ios/chrome/browser/payments/cells/price_item_unittest.mm
new file mode 100644
index 0000000..669ff376
--- /dev/null
+++ b/ios/chrome/browser/payments/cells/price_item_unittest.mm
@@ -0,0 +1,175 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/payments/cells/price_item.h"
+
+#import "ios/chrome/browser/ui/collection_view/cells/test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gtest_mac.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+
+// Tests that the labels are set properly after a call to |configureCell:|.
+TEST(PriceItemTest, TextLabels) {
+  PriceItem* priceItem = [[PriceItem alloc] initWithType:0];
+
+  NSString* item = @"Total";
+  NSString* notification = @"Updated";
+  NSString* price = @"USD $60.0";
+
+  priceItem.item = item;
+  priceItem.notification = notification;
+  priceItem.price = price;
+
+  id cell = [[[priceItem cellClass] alloc] init];
+  ASSERT_TRUE([cell isMemberOfClass:[PriceCell class]]);
+
+  PriceCell* priceCell = cell;
+  EXPECT_FALSE(priceCell.itemLabel.text);
+  EXPECT_FALSE(priceCell.notificationLabel.text);
+  EXPECT_FALSE(priceCell.priceLabel.text);
+
+  [priceItem configureCell:priceCell];
+  EXPECT_NSEQ(item, priceCell.itemLabel.text);
+  EXPECT_NSEQ(notification, priceCell.notificationLabel.text);
+  EXPECT_NSEQ(price, priceCell.priceLabel.text);
+}
+
+// Tests that the labels are provided with the correct amount of space.
+TEST(PriceItemTest, TextLabelTargetWidths) {
+  // Make the cell 164 wide so that after allocating 4 * kHorizontalPadding (16)
+  // space for the margins and area between the labels, there is 100 available.
+  // Accordingly, in each of the cases below where the sum of the desired label
+  // widths exceeds 100, the sum of the constraints should equal 100.
+  PriceCell* cell =
+      [[PriceCell alloc] initWithFrame:CGRectMake(0, 0, 164, 100)];
+
+  CGRect itemLabelRect = CGRectZero;
+  CGRect notificationLabelRect = CGRectZero;
+  CGRect priceLabelRect = CGRectZero;
+
+  // If there is enough room for all the labels they should be allowed their
+  // full widths.
+  itemLabelRect.size.width = 70;
+  notificationLabelRect.size.width = 10;
+  priceLabelRect.size.width = 20;
+  cell.itemLabel.frame = itemLabelRect;
+  cell.notificationLabel.frame = notificationLabelRect;
+  cell.priceLabel.frame = priceLabelRect;
+  EXPECT_EQ(70, [cell itemLabelTargetWidth]);
+  EXPECT_EQ(10, [cell notificationLabelTargetWidth]);
+  EXPECT_EQ(20, [cell priceLabelTargetWidth]);
+
+  itemLabelRect.size.width = 20;
+  notificationLabelRect.size.width = 70;
+  priceLabelRect.size.width = 10;
+  cell.itemLabel.frame = itemLabelRect;
+  cell.notificationLabel.frame = notificationLabelRect;
+  cell.priceLabel.frame = priceLabelRect;
+  EXPECT_EQ(20, [cell itemLabelTargetWidth]);
+  EXPECT_EQ(70, [cell notificationLabelTargetWidth]);
+  EXPECT_EQ(10, [cell priceLabelTargetWidth]);
+
+  itemLabelRect.size.width = 10;
+  notificationLabelRect.size.width = 20;
+  priceLabelRect.size.width = 70;
+  cell.itemLabel.frame = itemLabelRect;
+  cell.notificationLabel.frame = notificationLabelRect;
+  cell.priceLabel.frame = priceLabelRect;
+  EXPECT_EQ(10, [cell itemLabelTargetWidth]);
+  EXPECT_EQ(20, [cell notificationLabelTargetWidth]);
+  EXPECT_EQ(70, [cell priceLabelTargetWidth]);
+
+  // But once they exceed the available width, priority is given to the price
+  // label. It can take up to 50% of the available width before getting clipped.
+  // The item label gets clipped first, but never gets clipped to shorter than
+  // 50% of the remaining width.
+  itemLabelRect.size.width = 60;
+  notificationLabelRect.size.width = 20;
+  priceLabelRect.size.width = 50;
+  cell.itemLabel.frame = itemLabelRect;
+  cell.notificationLabel.frame = notificationLabelRect;
+  cell.priceLabel.frame = priceLabelRect;
+  EXPECT_EQ(30, [cell itemLabelTargetWidth]);
+  EXPECT_EQ(20, [cell notificationLabelTargetWidth]);
+  EXPECT_EQ(50, [cell priceLabelTargetWidth]);
+
+  // If that's not enough, the notification label gets clipped too.
+  itemLabelRect.size.width = 60;
+  notificationLabelRect.size.width = 40;
+  priceLabelRect.size.width = 50;
+  cell.itemLabel.frame = itemLabelRect;
+  cell.notificationLabel.frame = notificationLabelRect;
+  cell.priceLabel.frame = priceLabelRect;
+  EXPECT_EQ(25, [cell itemLabelTargetWidth]);
+  EXPECT_EQ(25, [cell notificationLabelTargetWidth]);
+  EXPECT_EQ(50, [cell priceLabelTargetWidth]);
+
+  // Unless the price label needs to take up more than 50% of the available
+  // width, in which case, it gets clipped too.
+  itemLabelRect.size.width = 60;
+  notificationLabelRect.size.width = 20;
+  priceLabelRect.size.width = 70;
+  cell.itemLabel.frame = itemLabelRect;
+  cell.notificationLabel.frame = notificationLabelRect;
+  cell.priceLabel.frame = priceLabelRect;
+  EXPECT_EQ(30, [cell itemLabelTargetWidth]);
+  EXPECT_EQ(20, [cell notificationLabelTargetWidth]);
+  EXPECT_EQ(50, [cell priceLabelTargetWidth]);
+
+  itemLabelRect.size.width = 60;
+  notificationLabelRect.size.width = 40;
+  priceLabelRect.size.width = 70;
+  cell.itemLabel.frame = itemLabelRect;
+  cell.notificationLabel.frame = notificationLabelRect;
+  cell.priceLabel.frame = priceLabelRect;
+  EXPECT_EQ(25, [cell itemLabelTargetWidth]);
+  EXPECT_EQ(25, [cell notificationLabelTargetWidth]);
+  EXPECT_EQ(50, [cell priceLabelTargetWidth]);
+
+  // Test the scenario where the notification label is nil. Make the cell 148
+  // wide so that after allocating 3 * kHorizontalPadding (16) space for the
+  // margins and area between the labels, there is 100 available.
+  cell = [[PriceCell alloc] initWithFrame:CGRectMake(0, 0, 148, 100)];
+  cell.notificationLabel.frame = CGRectZero;
+
+  // If there is enough room for both item and price labels they should be
+  // allowed their full widths.
+  itemLabelRect.size.width = 90;
+  priceLabelRect.size.width = 10;
+  cell.itemLabel.frame = itemLabelRect;
+  cell.priceLabel.frame = priceLabelRect;
+  EXPECT_EQ(90, [cell itemLabelTargetWidth]);
+  EXPECT_EQ(10, [cell priceLabelTargetWidth]);
+
+  itemLabelRect.size.width = 10;
+  priceLabelRect.size.width = 90;
+  cell.itemLabel.frame = itemLabelRect;
+  cell.priceLabel.frame = priceLabelRect;
+  EXPECT_EQ(10, [cell itemLabelTargetWidth]);
+  EXPECT_EQ(90, [cell priceLabelTargetWidth]);
+
+  // But once they exceed the available width, start clipping the item label.
+  itemLabelRect.size.width = 90;
+  priceLabelRect.size.width = 50;
+  cell.itemLabel.frame = itemLabelRect;
+  cell.priceLabel.frame = priceLabelRect;
+  EXPECT_EQ(50, [cell itemLabelTargetWidth]);
+  EXPECT_EQ(50, [cell priceLabelTargetWidth]);
+
+  // Unless the price label wants to take up more than 50% of the available
+  // width, in which case, it gets clipped too.
+  itemLabelRect.size.width = 90;
+  priceLabelRect.size.width = 60;
+  cell.itemLabel.frame = itemLabelRect;
+  cell.priceLabel.frame = priceLabelRect;
+  EXPECT_EQ(50, [cell itemLabelTargetWidth]);
+  EXPECT_EQ(50, [cell priceLabelTargetWidth]);
+}
+
+}  // namespace
diff --git a/ios/chrome/browser/payments/payment_items_display_view_controller.mm b/ios/chrome/browser/payments/payment_items_display_view_controller.mm
index fb2dba1..d527bee 100644
--- a/ios/chrome/browser/payments/payment_items_display_view_controller.mm
+++ b/ios/chrome/browser/payments/payment_items_display_view_controller.mm
@@ -10,8 +10,8 @@
 #include "base/strings/sys_string_conversions.h"
 #include "components/autofill/core/browser/credit_card.h"
 #include "components/strings/grit/components_strings.h"
+#import "ios/chrome/browser/payments/cells/price_item.h"
 #import "ios/chrome/browser/payments/payment_request_utils.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
@@ -142,15 +142,15 @@
   [model addSectionWithIdentifier:SectionIdentifierPayment];
 
   // Add the total entry.
-  CollectionViewDetailItem* totalItem = [[[CollectionViewDetailItem alloc]
-      initWithType:ItemTypePaymentItemTotal] autorelease];
+  PriceItem* totalItem =
+      [[[PriceItem alloc] initWithType:ItemTypePaymentItemTotal] autorelease];
   totalItem.accessibilityIdentifier = kPaymentItemsDisplayItemId;
-  totalItem.text = base::SysUTF16ToNSString(_total.label);
+  totalItem.item = base::SysUTF16ToNSString(_total.label);
 
   NSString* currencyCode = base::SysUTF16ToNSString(_total.amount.currency);
   NSDecimalNumber* value = [NSDecimalNumber
       decimalNumberWithString:SysUTF16ToNSString(_total.amount.value)];
-  totalItem.detailText =
+  totalItem.price =
       payment_request_utils::FormattedCurrencyString(value, currencyCode);
 
   [model addItem:totalItem toSectionWithIdentifier:SectionIdentifierPayment];
@@ -158,17 +158,16 @@
   // Add the line item entries.
   for (size_t i = 0; i < _paymentItems.size(); ++i) {
     web::PaymentItem paymentItem = _paymentItems[i];
-    CollectionViewDetailItem* paymentItemItem =
-        [[[CollectionViewDetailItem alloc] initWithType:ItemTypePaymentItem]
-            autorelease];
+    PriceItem* paymentItemItem =
+        [[[PriceItem alloc] initWithType:ItemTypePaymentItem] autorelease];
     paymentItemItem.accessibilityIdentifier = kPaymentItemsDisplayItemId;
-    paymentItemItem.text = base::SysUTF16ToNSString(paymentItem.label);
+    paymentItemItem.item = base::SysUTF16ToNSString(paymentItem.label);
 
     NSString* currencyCode =
         base::SysUTF16ToNSString(paymentItem.amount.currency);
     NSDecimalNumber* value = [NSDecimalNumber
         decimalNumberWithString:SysUTF16ToNSString(paymentItem.amount.value)];
-    paymentItemItem.detailText =
+    paymentItemItem.price =
         payment_request_utils::FormattedCurrencyString(value, currencyCode);
     [model addItem:paymentItemItem
         toSectionWithIdentifier:SectionIdentifierPayment];
@@ -196,26 +195,24 @@
       [self.collectionViewModel itemTypeForIndexPath:indexPath];
   switch (itemType) {
     case ItemTypePaymentItemTotal: {
-      CollectionViewDetailCell* detailCell =
-          base::mac::ObjCCastStrict<CollectionViewDetailCell>(cell);
-      detailCell.textLabel.font =
+      PriceCell* priceCell = base::mac::ObjCCastStrict<PriceCell>(cell);
+      priceCell.itemLabel.font =
           [[MDFRobotoFontLoader sharedInstance] boldFontOfSize:14];
-      detailCell.textLabel.textColor = [[MDCPalette greyPalette] tint600];
-      detailCell.detailTextLabel.font =
+      priceCell.itemLabel.textColor = [[MDCPalette greyPalette] tint600];
+      priceCell.priceLabel.font =
           [[MDFRobotoFontLoader sharedInstance] boldFontOfSize:14];
-      detailCell.detailTextLabel.textColor = [[MDCPalette greyPalette] tint900];
+      priceCell.priceLabel.textColor = [[MDCPalette greyPalette] tint900];
       break;
     }
     case ItemTypePaymentItem: {
-      CollectionViewDetailCell* detailCell =
-          base::mac::ObjCCastStrict<CollectionViewDetailCell>(cell);
-      detailCell.textLabel.font =
+      PriceCell* priceCell = base::mac::ObjCCastStrict<PriceCell>(cell);
+      priceCell.itemLabel.font =
           [[MDFRobotoFontLoader sharedInstance] regularFontOfSize:14];
-      detailCell.textLabel.textColor = [[MDCPalette greyPalette] tint900];
+      priceCell.itemLabel.textColor = [[MDCPalette greyPalette] tint900];
 
-      detailCell.detailTextLabel.font =
+      priceCell.priceLabel.font =
           [[MDFRobotoFontLoader sharedInstance] regularFontOfSize:14];
-      detailCell.detailTextLabel.textColor = [[MDCPalette greyPalette] tint900];
+      priceCell.priceLabel.textColor = [[MDCPalette greyPalette] tint900];
       break;
     }
     default:
diff --git a/ios/chrome/browser/payments/payment_method_selection_view_controller.mm b/ios/chrome/browser/payments/payment_method_selection_view_controller.mm
index 6819fab..a17b3e0 100644
--- a/ios/chrome/browser/payments/payment_method_selection_view_controller.mm
+++ b/ios/chrome/browser/payments/payment_method_selection_view_controller.mm
@@ -5,18 +5,24 @@
 #import "ios/chrome/browser/payments/payment_method_selection_view_controller.h"
 
 #import "base/ios/weak_nsobject.h"
+#include "base/mac/foundation_util.h"
 #include "base/mac/scoped_nsobject.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/autofill/core/browser/autofill_data_util.h"
 #include "components/autofill/core/browser/credit_card.h"
 #include "components/strings/grit/components_strings.h"
+#import "ios/chrome/browser/payments/cells/payments_text_item.h"
 #import "ios/chrome/browser/payments/cells/payment_method_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
+#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
+#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/chrome/browser/ui/icons/chrome_icon.h"
+#include "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
+#include "ios/chrome/grit/ios_theme_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 
@@ -101,9 +107,7 @@
     int methodTypeIconID =
         autofill::data_util::GetPaymentRequestData(paymentMethod->type())
             .icon_resource_id;
-    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-    paymentMethodItem.methodTypeIcon =
-        rb.GetNativeImageNamed(methodTypeIconID).ToUIImage();
+    paymentMethodItem.methodTypeIcon = NativeImage(methodTypeIconID);
 
     if (paymentMethod == _selectedPaymentMethod)
       paymentMethodItem.accessoryType = MDCCollectionViewCellAccessoryCheckmark;
@@ -111,10 +115,11 @@
         toSectionWithIdentifier:SectionIdentifierPayment];
   }
 
-  CollectionViewTextItem* addPaymentMethod = [[[CollectionViewTextItem alloc]
-      initWithType:ItemTypeAddMethod] autorelease];
+  PaymentsTextItem* addPaymentMethod =
+      [[[PaymentsTextItem alloc] initWithType:ItemTypeAddMethod] autorelease];
   addPaymentMethod.text =
       l10n_util::GetNSString(IDS_IOS_PAYMENT_REQUEST_ADD_METHOD_BUTTON);
+  addPaymentMethod.image = NativeImage(IDR_IOS_PAYMENTS_ADD);
   addPaymentMethod.accessibilityTraits |= UIAccessibilityTraitButton;
   [model addItem:addPaymentMethod
       toSectionWithIdentifier:SectionIdentifierPayment];
@@ -153,11 +158,19 @@
 
 - (CGFloat)collectionView:(UICollectionView*)collectionView
     cellHeightAtIndexPath:(NSIndexPath*)indexPath {
-  NSInteger type = [self.collectionViewModel itemTypeForIndexPath:indexPath];
-  if (type == ItemTypeAddMethod)
-    return MDCCellDefaultOneLineHeight;
-  else
-    return MDCCellDefaultTwoLineHeight;
+  CollectionViewItem* item =
+      [self.collectionViewModel itemAtIndexPath:indexPath];
+  switch (item.type) {
+    case ItemTypePaymentMethod:
+      return MDCCellDefaultTwoLineHeight;
+    case ItemTypeAddMethod:
+      return [MDCCollectionViewCell
+          cr_preferredHeightForWidth:CGRectGetWidth(collectionView.bounds)
+                             forItem:item];
+    default:
+      NOTREACHED();
+      return MDCCellDefaultOneLineHeight;
+  }
 }
 
 @end
diff --git a/ios/chrome/browser/payments/payment_method_selection_view_controller_unittest.mm b/ios/chrome/browser/payments/payment_method_selection_view_controller_unittest.mm
new file mode 100644
index 0000000..e0eacf4f
--- /dev/null
+++ b/ios/chrome/browser/payments/payment_method_selection_view_controller_unittest.mm
@@ -0,0 +1,73 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/payments/payment_method_selection_view_controller.h"
+
+#include <vector>
+
+#include "base/mac/foundation_util.h"
+#include "components/autofill/core/browser/credit_card.h"
+#import "ios/chrome/browser/payments/cells/payments_text_item.h"
+#import "ios/chrome/browser/payments/cells/payment_method_item.h"
+#import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h"
+#include "ios/chrome/grit/ios_strings.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class PaymentMethodSelectionViewControllerTest
+    : public CollectionViewControllerTest {
+ protected:
+  CollectionViewController* NewController() override NS_RETURNS_RETAINED {
+    return [[PaymentMethodSelectionViewController alloc] init];
+  }
+
+  PaymentMethodSelectionViewController* PaymentMethodSelectionController() {
+    return base::mac::ObjCCastStrict<PaymentMethodSelectionViewController>(
+        controller());
+  }
+};
+
+// Tests that the correct number of items are displayed after loading the model
+// and that the correct item appears to be selected.
+TEST_F(PaymentMethodSelectionViewControllerTest, TestModel) {
+  CreateController();
+  CheckController();
+  CheckTitleWithId(IDS_IOS_PAYMENT_REQUEST_METHOD_SELECTION_TITLE);
+
+  std::unique_ptr<autofill::CreditCard> creditCard1(new autofill::CreditCard());
+  std::unique_ptr<autofill::CreditCard> creditCard2(new autofill::CreditCard());
+
+  std::vector<autofill::CreditCard*> creditCards;
+  creditCards.push_back(creditCard1.get());
+  creditCards.push_back(creditCard2.get());
+
+  [PaymentMethodSelectionController() setPaymentMethods:creditCards];
+  [PaymentMethodSelectionController() setSelectedPaymentMethod:creditCards[0]];
+  [PaymentMethodSelectionController() loadModel];
+
+  ASSERT_EQ(1, NumberOfSections());
+  // One item for each of payment method plus 1 for the add button.
+  EXPECT_EQ(3U, static_cast<unsigned int>(NumberOfItemsInSection(0)));
+
+  // The first two items should be of type ShippingAddressItem. The first one
+  // should appear to be selected.
+  id item = GetCollectionViewItem(0, 0);
+  ASSERT_TRUE([item isMemberOfClass:[PaymentMethodItem class]]);
+  PaymentMethodItem* paymentMethodItem = item;
+  EXPECT_EQ(MDCCollectionViewCellAccessoryCheckmark,
+            paymentMethodItem.accessoryType);
+
+  item = GetCollectionViewItem(0, 1);
+  ASSERT_TRUE([item isMemberOfClass:[PaymentMethodItem class]]);
+  paymentMethodItem = item;
+  EXPECT_EQ(MDCCollectionViewCellAccessoryNone,
+            paymentMethodItem.accessoryType);
+
+  // The last item should also be of type TextAndMessageItem.
+  item = GetCollectionViewItem(0, 2);
+  ASSERT_TRUE([item isMemberOfClass:[PaymentsTextItem class]]);
+}
+
+}  // namespace
diff --git a/ios/chrome/browser/payments/payment_request_view_controller.mm b/ios/chrome/browser/payments/payment_request_view_controller.mm
index acef1f7..94cf058 100644
--- a/ios/chrome/browser/payments/payment_request_view_controller.mm
+++ b/ios/chrome/browser/payments/payment_request_view_controller.mm
@@ -18,6 +18,7 @@
 #include "ios/chrome/browser/application_context.h"
 #import "ios/chrome/browser/payments/cells/page_info_item.h"
 #import "ios/chrome/browser/payments/cells/payment_method_item.h"
+#import "ios/chrome/browser/payments/cells/price_item.h"
 #import "ios/chrome/browser/payments/cells/shipping_address_item.h"
 #import "ios/chrome/browser/payments/payment_request_utils.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h"
@@ -27,6 +28,7 @@
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
+#include "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h"
 #import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
@@ -73,7 +75,7 @@
   base::scoped_nsobject<UIBarButtonItem> _cancelButton;
   base::scoped_nsobject<MDCFlatButton> _payButton;
 
-  CollectionViewDetailItem* _paymentSummaryItem;
+  PriceItem* _paymentSummaryItem;
   ShippingAddressItem* _selectedShippingAddressItem;
   CollectionViewTextItem* _selectedShippingOptionItem;
 
@@ -206,8 +208,8 @@
   pageInfo.pageHost = _pageHost;
   [model setHeader:pageInfo forSectionWithIdentifier:SectionIdentifierSummary];
 
-  _paymentSummaryItem = [[[CollectionViewDetailItem alloc]
-      initWithType:ItemTypeSummaryTotal] autorelease];
+  _paymentSummaryItem =
+      [[[PriceItem alloc] initWithType:ItemTypeSummaryTotal] autorelease];
   [self fillPaymentSummaryItem:_paymentSummaryItem
                withPaymentItem:_paymentRequest.details.total];
   if (!_paymentRequest.details.display_items.empty()) {
@@ -294,9 +296,7 @@
         autofill::data_util::GetPaymentRequestData(
             _selectedPaymentMethod->type())
             .icon_resource_id;
-    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-    paymentMethod.methodTypeIcon =
-        rb.GetNativeImageNamed(selectedMethodCardTypeIconID).ToUIImage();
+    paymentMethod.methodTypeIcon = NativeImage(selectedMethodCardTypeIconID);
 
     paymentMethod.accessoryType =
         MDCCollectionViewCellAccessoryDisclosureIndicator;
@@ -359,15 +359,15 @@
 
 #pragma mark - Helper methods
 
-- (void)fillPaymentSummaryItem:(CollectionViewDetailItem*)item
+- (void)fillPaymentSummaryItem:(PriceItem*)item
                withPaymentItem:(web::PaymentItem)paymentItem {
-  item.text = l10n_util::GetNSString(IDS_IOS_PAYMENT_REQUEST_TOTAL_HEADER);
+  item.item = l10n_util::GetNSString(IDS_IOS_PAYMENT_REQUEST_TOTAL_HEADER);
   NSString* currencyCode =
       base::SysUTF16ToNSString(_paymentRequest.details.total.amount.currency);
   NSDecimalNumber* value = [NSDecimalNumber
       decimalNumberWithString:SysUTF16ToNSString(
                                   _paymentRequest.details.total.amount.value)];
-  item.detailText =
+  item.price =
       payment_request_utils::FormattedCurrencyString(value, currencyCode);
 }
 
diff --git a/ios/chrome/browser/payments/shipping_address_selection_view_controller.h b/ios/chrome/browser/payments/shipping_address_selection_view_controller.h
index 0e55925..3ca78b4 100644
--- a/ios/chrome/browser/payments/shipping_address_selection_view_controller.h
+++ b/ios/chrome/browser/payments/shipping_address_selection_view_controller.h
@@ -44,6 +44,12 @@
 // The shipping address selected by the user, if any.
 @property(nonatomic, assign) autofill::AutofillProfile* selectedShippingAddress;
 
+// Whether or not the view is in a loading state.
+@property(nonatomic, assign) BOOL isLoading;
+
+// The error message to display, if any.
+@property(nonatomic, assign) NSString* errorMessage;
+
 // The delegate to be notified when the user selects a shipping address or
 // returns without selecting one.
 @property(nonatomic, weak) id<ShippingAddressSelectionViewControllerDelegate>
diff --git a/ios/chrome/browser/payments/shipping_address_selection_view_controller.mm b/ios/chrome/browser/payments/shipping_address_selection_view_controller.mm
index 556bada..c5dec12 100644
--- a/ios/chrome/browser/payments/shipping_address_selection_view_controller.mm
+++ b/ios/chrome/browser/payments/shipping_address_selection_view_controller.mm
@@ -11,14 +11,19 @@
 #include "components/autofill/core/browser/autofill_profile.h"
 #include "components/strings/grit/components_strings.h"
 #include "ios/chrome/browser/application_context.h"
+#import "ios/chrome/browser/payments/cells/payments_text_item.h"
 #import "ios/chrome/browser/payments/cells/shipping_address_item.h"
 #import "ios/chrome/browser/payments/payment_request_utils.h"
-#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
+#import "ios/chrome/browser/ui/autofill/cells/status_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
+#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
+#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/chrome/browser/ui/icons/chrome_icon.h"
+#include "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
+#include "ios/chrome/grit/ios_theme_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
 using payment_request_utils::NameLabelFromAutofillProfile;
@@ -37,7 +42,8 @@
 };
 
 typedef NS_ENUM(NSInteger, ItemType) {
-  ItemTypeMessage = kItemTypeEnumZero,
+  ItemTypeSpinner = kItemTypeEnumZero,
+  ItemTypeMessage,
   ItemTypeShippingAddress,  // This is a repeated item type.
   ItemTypeAddShippingAddress,
 };
@@ -60,6 +66,8 @@
 
 @synthesize selectedShippingAddress = _selectedShippingAddress;
 @synthesize shippingAddresses = _shippingAddresses;
+@synthesize isLoading = _isLoading;
+@synthesize errorMessage = _errorMessage;
 
 - (instancetype)init {
   if ((self = [super initWithStyle:CollectionViewControllerStyleAppBar])) {
@@ -94,9 +102,32 @@
 - (void)loadModel {
   [super loadModel];
   CollectionViewModel* model = self.collectionViewModel;
+  _selectedItem = nil;
 
   [model addSectionWithIdentifier:SectionIdentifierShippingAddress];
 
+  if (_isLoading) {
+    StatusItem* statusItem =
+        [[[StatusItem alloc] initWithType:ItemTypeSpinner] autorelease];
+    statusItem.text =
+        l10n_util::GetNSString(IDS_IOS_PAYMENT_REQUEST_CHECKING_LABEL);
+    [model addItem:statusItem
+        toSectionWithIdentifier:SectionIdentifierShippingAddress];
+    return;
+  }
+
+  PaymentsTextItem* messageItem =
+      [[[PaymentsTextItem alloc] initWithType:ItemTypeMessage] autorelease];
+  if (_errorMessage) {
+    messageItem.text = _errorMessage;
+    messageItem.image = NativeImage(IDR_IOS_PAYMENTS_WARNING);
+  } else {
+    messageItem.text = l10n_util::GetNSString(
+        IDS_IOS_PAYMENT_REQUEST_SHIPPING_ADDRESS_SELECTION_MESSAGE);
+  }
+  [model addItem:messageItem
+      toSectionWithIdentifier:SectionIdentifierShippingAddress];
+
   for (size_t i = 0; i < _shippingAddresses.size(); ++i) {
     autofill::AutofillProfile* shippingAddress = _shippingAddresses[i];
     ShippingAddressItem* item = [[[ShippingAddressItem alloc]
@@ -109,15 +140,15 @@
       item.accessoryType = MDCCollectionViewCellAccessoryCheckmark;
       _selectedItem = item;
     }
-
     [model addItem:item
         toSectionWithIdentifier:SectionIdentifierShippingAddress];
   }
 
-  CollectionViewTextItem* addShippingAddress = [[[CollectionViewTextItem alloc]
+  PaymentsTextItem* addShippingAddress = [[[PaymentsTextItem alloc]
       initWithType:ItemTypeAddShippingAddress] autorelease];
   addShippingAddress.text = l10n_util::GetNSString(
       IDS_IOS_PAYMENT_REQUEST_SHIPPING_ADDRESS_SELECTION_ADD_BUTTON);
+  addShippingAddress.image = NativeImage(IDR_IOS_PAYMENTS_ADD);
   addShippingAddress.accessibilityTraits |= UIAccessibilityTraitButton;
   [model addItem:addShippingAddress
       toSectionWithIdentifier:SectionIdentifierShippingAddress];
@@ -134,6 +165,36 @@
       UIEdgeInsetsMake(0, kSeparatorEdgeInset, 0, kSeparatorEdgeInset);
 }
 
+#pragma mark UICollectionViewDataSource
+
+- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView
+                 cellForItemAtIndexPath:(nonnull NSIndexPath*)indexPath {
+  UICollectionViewCell* cell =
+      [super collectionView:collectionView cellForItemAtIndexPath:indexPath];
+
+  NSInteger itemType =
+      [self.collectionViewModel itemTypeForIndexPath:indexPath];
+  switch (itemType) {
+    case ItemTypeMessage: {
+      PaymentsTextCell* messageCell =
+          base::mac::ObjCCastStrict<PaymentsTextCell>(cell);
+      messageCell.textLabel.textColor =
+          _errorMessage ? [[MDCPalette cr_redPalette] tint600]
+                        : [[MDCPalette greyPalette] tint600];
+      break;
+    }
+    case ItemTypeAddShippingAddress: {
+      PaymentsTextCell* addAddressCell =
+          base::mac::ObjCCastStrict<PaymentsTextCell>(cell);
+      addAddressCell.textLabel.textColor = [[MDCPalette greyPalette] tint900];
+      break;
+    }
+    default:
+      break;
+  }
+  return cell;
+}
+
 #pragma mark UICollectionViewDelegate
 
 - (void)collectionView:(UICollectionView*)collectionView
@@ -142,29 +203,29 @@
 
   CollectionViewModel* model = self.collectionViewModel;
 
-  NSInteger itemType = [model itemTypeForIndexPath:indexPath];
-  if (itemType == ItemTypeShippingAddress) {
-    NSIndexPath* currentlySelectedIndexPath = [self.collectionViewModel
-               indexPathForItem:_selectedItem
-        inSectionWithIdentifier:SectionIdentifierShippingAddress];
-    if (currentlySelectedIndexPath != indexPath) {
-      // Update the cells.
-      CollectionViewItem* item = [model itemAtIndexPath:indexPath];
-      ShippingAddressItem* newlySelectedItem =
-          base::mac::ObjCCastStrict<ShippingAddressItem>(item);
-      newlySelectedItem.accessoryType = MDCCollectionViewCellAccessoryCheckmark;
-
+  CollectionViewItem* item = [model itemAtIndexPath:indexPath];
+  if (item.type == ItemTypeShippingAddress) {
+    // Update the currently selected cell, if any.
+    if (_selectedItem) {
       _selectedItem.accessoryType = MDCCollectionViewCellAccessoryNone;
-
-      [self reconfigureCellsForItems:@[ _selectedItem, newlySelectedItem ]
+      [self reconfigureCellsForItems:@[ _selectedItem ]
              inSectionWithIdentifier:SectionIdentifierShippingAddress];
-
-      // Update the selected shipping address and its respective item.
-      NSInteger index = [model indexInItemTypeForIndexPath:indexPath];
-      DCHECK(index < (NSInteger)_shippingAddresses.size());
-      self.selectedShippingAddress = _shippingAddresses[index];
-      _selectedItem = newlySelectedItem;
     }
+
+    // Update the newly selected cell.
+    ShippingAddressItem* newlySelectedItem =
+        base::mac::ObjCCastStrict<ShippingAddressItem>(item);
+    newlySelectedItem.accessoryType = MDCCollectionViewCellAccessoryCheckmark;
+    [self reconfigureCellsForItems:@[ newlySelectedItem ]
+           inSectionWithIdentifier:SectionIdentifierShippingAddress];
+
+    // Update the selected shipping address and its respective item.
+    NSInteger index = [model indexInItemTypeForIndexPath:indexPath];
+    DCHECK(index < (NSInteger)_shippingAddresses.size());
+    self.selectedShippingAddress = _shippingAddresses[index];
+    _selectedItem = newlySelectedItem;
+
+    // Notify the delegate of the selection.
     [_delegate
         shippingAddressSelectionViewController:self
                        selectedShippingAddress:self.selectedShippingAddress];
@@ -177,15 +238,29 @@
 
 - (CGFloat)collectionView:(UICollectionView*)collectionView
     cellHeightAtIndexPath:(NSIndexPath*)indexPath {
+  CollectionViewItem* item =
+      [self.collectionViewModel itemAtIndexPath:indexPath];
+  switch (item.type) {
+    case ItemTypeSpinner:
+    case ItemTypeMessage:
+    case ItemTypeShippingAddress:
+    case ItemTypeAddShippingAddress:
+      return [MDCCollectionViewCell
+          cr_preferredHeightForWidth:CGRectGetWidth(collectionView.bounds)
+                             forItem:item];
+    default:
+      NOTREACHED();
+      return MDCCellDefaultOneLineHeight;
+  }
+}
+
+- (BOOL)collectionView:(UICollectionView*)collectionView
+    hidesInkViewAtIndexPath:(NSIndexPath*)indexPath {
   NSInteger type = [self.collectionViewModel itemTypeForIndexPath:indexPath];
-  if (type == ItemTypeAddShippingAddress) {
-    return MDCCellDefaultOneLineHeight;
+  if (type == ItemTypeMessage) {
+    return YES;
   } else {
-    CollectionViewItem* item =
-        [self.collectionViewModel itemAtIndexPath:indexPath];
-    return [MDCCollectionViewCell
-        cr_preferredHeightForWidth:CGRectGetWidth(collectionView.bounds)
-                           forItem:item];
+    return NO;
   }
 }
 
diff --git a/ios/chrome/browser/payments/shipping_address_selection_view_controller_unittest.mm b/ios/chrome/browser/payments/shipping_address_selection_view_controller_unittest.mm
index 4b09985f..86a0c79 100644
--- a/ios/chrome/browser/payments/shipping_address_selection_view_controller_unittest.mm
+++ b/ios/chrome/browser/payments/shipping_address_selection_view_controller_unittest.mm
@@ -2,12 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#import "ios/chrome/browser/payments/shipping_address_selection_view_controller.h"
+
 #include <vector>
 
 #include "base/mac/foundation_util.h"
 #include "components/autofill/core/browser/autofill_profile.h"
-#import "ios/chrome/browser/payments/shipping_address_selection_view_controller.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
+#import "ios/chrome/browser/payments/cells/payments_text_item.h"
+#import "ios/chrome/browser/payments/cells/shipping_address_item.h"
+#import "ios/chrome/browser/ui/autofill/cells/status_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -49,15 +52,50 @@
   [ShippingAddressSelectionController() loadModel];
 
   ASSERT_EQ(1, NumberOfSections());
-  // One item for each of shipping addresses plus 1 for the add button.
-  EXPECT_EQ(shippingAddresses.size() + 1,
-            static_cast<unsigned int>(NumberOfItemsInSection(0)));
+  // One item for each of shipping addresses plus 2 for the message and the add
+  // button.
+  EXPECT_EQ(4U, static_cast<unsigned int>(NumberOfItemsInSection(0)));
 
-  // The first address should appear to be selected.
-  CollectionViewTextItem* item = GetCollectionViewItem(0, 0);
-  EXPECT_EQ(MDCCollectionViewCellAccessoryCheckmark, item.accessoryType);
+  // The first item should be of type TextAndMessageItem.
+  id item = GetCollectionViewItem(0, 0);
+  ASSERT_TRUE([item isMemberOfClass:[PaymentsTextItem class]]);
+
+  // The next two items should be of type ShippingAddressItem. The first one
+  // should appear to be selected.
   item = GetCollectionViewItem(0, 1);
-  EXPECT_EQ(MDCCollectionViewCellAccessoryNone, item.accessoryType);
+  ASSERT_TRUE([item isMemberOfClass:[ShippingAddressItem class]]);
+  ShippingAddressItem* shippingAddressItem = item;
+  EXPECT_EQ(MDCCollectionViewCellAccessoryCheckmark,
+            shippingAddressItem.accessoryType);
+
+  item = GetCollectionViewItem(0, 2);
+  ASSERT_TRUE([item isMemberOfClass:[ShippingAddressItem class]]);
+  shippingAddressItem = item;
+  EXPECT_EQ(MDCCollectionViewCellAccessoryNone,
+            shippingAddressItem.accessoryType);
+
+  // The last item should also be of type TextAndMessageItem.
+  item = GetCollectionViewItem(0, 3);
+  ASSERT_TRUE([item isMemberOfClass:[PaymentsTextItem class]]);
+
+  // Test the error state.
+  [ShippingAddressSelectionController() setErrorMessage:@"Lorem ipsum"];
+  [ShippingAddressSelectionController() loadModel];
+  ASSERT_EQ(1, NumberOfSections());
+  // There should stil be 4 items in total.
+  EXPECT_EQ(4U, static_cast<unsigned int>(NumberOfItemsInSection(0)));
+
+  // Test the loading state.
+  [ShippingAddressSelectionController() setIsLoading:YES];
+  [ShippingAddressSelectionController() loadModel];
+
+  ASSERT_EQ(1, NumberOfSections());
+  // There should be only one item.
+  EXPECT_EQ(1U, static_cast<unsigned int>(NumberOfItemsInSection(0)));
+
+  // The item should be of type StatusItem.
+  item = GetCollectionViewItem(0, 0);
+  ASSERT_TRUE([item isMemberOfClass:[StatusItem class]]);
 }
 
 }  // namespace
diff --git a/ios/chrome/browser/payments/shipping_option_selection_view_controller.h b/ios/chrome/browser/payments/shipping_option_selection_view_controller.h
index 073ef4e..8739fda 100644
--- a/ios/chrome/browser/payments/shipping_option_selection_view_controller.h
+++ b/ios/chrome/browser/payments/shipping_option_selection_view_controller.h
@@ -40,6 +40,12 @@
 // The shipping option selected by the user, if any.
 @property(nonatomic, assign) web::PaymentShippingOption* selectedShippingOption;
 
+// Whether or not the view is in a loading state.
+@property(nonatomic, assign) BOOL isLoading;
+
+// The error message to display, if any.
+@property(nonatomic, assign) NSString* errorMessage;
+
 // The delegate to be notified when the user selects a shipping option or
 // returns without selecting one.
 @property(nonatomic, weak) id<ShippingOptionSelectionViewControllerDelegate>
diff --git a/ios/chrome/browser/payments/shipping_option_selection_view_controller.mm b/ios/chrome/browser/payments/shipping_option_selection_view_controller.mm
index fa2bfbc..3f2fe64 100644
--- a/ios/chrome/browser/payments/shipping_option_selection_view_controller.mm
+++ b/ios/chrome/browser/payments/shipping_option_selection_view_controller.mm
@@ -8,12 +8,18 @@
 #include "base/mac/foundation_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/strings/grit/components_strings.h"
+#import "ios/chrome/browser/payments/cells/payments_text_item.h"
 #import "ios/chrome/browser/payments/payment_request_utils.h"
+#import "ios/chrome/browser/ui/autofill/cells/status_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
+#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
+#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/chrome/browser/ui/icons/chrome_icon.h"
+#include "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
+#include "ios/chrome/grit/ios_theme_resources.h"
 #import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
 #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -30,7 +36,9 @@
 };
 
 typedef NS_ENUM(NSInteger, ItemType) {
-  ItemTypeShippingOption = kItemTypeEnumZero,  // This is a repeated item type.
+  ItemTypeSpinner = kItemTypeEnumZero,
+  ItemTypeMessage,
+  ItemTypeShippingOption,  // This is a repeated item type.
 };
 
 }  // namespace
@@ -51,6 +59,8 @@
 
 @synthesize shippingOptions = _shippingOptions;
 @synthesize selectedShippingOption = _selectedShippingOption;
+@synthesize isLoading = _isLoading;
+@synthesize errorMessage = _errorMessage;
 
 - (instancetype)init {
   if ((self = [super initWithStyle:CollectionViewControllerStyleAppBar])) {
@@ -85,9 +95,29 @@
 - (void)loadModel {
   [super loadModel];
   CollectionViewModel* model = self.collectionViewModel;
+  _selectedItem = nil;
 
   [model addSectionWithIdentifier:SectionIdentifierShippingOption];
 
+  if (self.isLoading) {
+    StatusItem* statusItem =
+        [[[StatusItem alloc] initWithType:ItemTypeSpinner] autorelease];
+    statusItem.text =
+        l10n_util::GetNSString(IDS_IOS_PAYMENT_REQUEST_CHECKING_LABEL);
+    [model addItem:statusItem
+        toSectionWithIdentifier:SectionIdentifierShippingOption];
+    return;
+  }
+
+  if (_errorMessage) {
+    PaymentsTextItem* messageItem =
+        [[[PaymentsTextItem alloc] initWithType:ItemTypeMessage] autorelease];
+    messageItem.text = _errorMessage;
+    messageItem.image = NativeImage(IDR_IOS_PAYMENTS_WARNING);
+    [model addItem:messageItem
+        toSectionWithIdentifier:SectionIdentifierShippingOption];
+  }
+
   for (size_t i = 0; i < _shippingOptions.size(); ++i) {
     web::PaymentShippingOption* shippingOption = _shippingOptions[i];
     CollectionViewTextItem* item = [[[CollectionViewTextItem alloc]
@@ -128,6 +158,28 @@
       UIEdgeInsetsMake(0, kSeparatorEdgeInset, 0, kSeparatorEdgeInset);
 }
 
+#pragma mark UICollectionViewDataSource
+
+- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView
+                 cellForItemAtIndexPath:(nonnull NSIndexPath*)indexPath {
+  UICollectionViewCell* cell =
+      [super collectionView:collectionView cellForItemAtIndexPath:indexPath];
+
+  NSInteger itemType =
+      [self.collectionViewModel itemTypeForIndexPath:indexPath];
+  switch (itemType) {
+    case ItemTypeMessage: {
+      PaymentsTextCell* messageCell =
+          base::mac::ObjCCastStrict<PaymentsTextCell>(cell);
+      messageCell.textLabel.textColor = [[MDCPalette cr_redPalette] tint600];
+      break;
+    }
+    default:
+      break;
+  }
+  return cell;
+}
+
 #pragma mark UICollectionViewDelegate
 
 - (void)collectionView:(UICollectionView*)collectionView
@@ -136,23 +188,20 @@
 
   CollectionViewModel* model = self.collectionViewModel;
 
-  NSInteger itemType =
-      [self.collectionViewModel itemTypeForIndexPath:indexPath];
-  DCHECK(ItemTypeShippingOption == itemType);
+  CollectionViewItem* item = [model itemAtIndexPath:indexPath];
+  if (item.type == ItemTypeShippingOption) {
+    // Update the currently selected cell, if any.
+    if (_selectedItem) {
+      _selectedItem.accessoryType = MDCCollectionViewCellAccessoryNone;
+      [self reconfigureCellsForItems:@[ _selectedItem ]
+             inSectionWithIdentifier:SectionIdentifierShippingOption];
+    }
 
-  NSIndexPath* currentlySelectedIndexPath = [self.collectionViewModel
-             indexPathForItem:_selectedItem
-      inSectionWithIdentifier:SectionIdentifierShippingOption];
-  if (currentlySelectedIndexPath != indexPath) {
-    // Update the cells.
-    CollectionViewItem* item = [model itemAtIndexPath:indexPath];
+    // Update the newly selected cell.
     CollectionViewTextItem* newlySelectedItem =
         base::mac::ObjCCastStrict<CollectionViewTextItem>(item);
     newlySelectedItem.accessoryType = MDCCollectionViewCellAccessoryCheckmark;
-
-    _selectedItem.accessoryType = MDCCollectionViewCellAccessoryNone;
-
-    [self reconfigureCellsForItems:@[ _selectedItem, newlySelectedItem ]
+    [self reconfigureCellsForItems:@[ newlySelectedItem ]
            inSectionWithIdentifier:SectionIdentifierShippingOption];
 
     // Update the selected shipping option and its respective item.
@@ -160,16 +209,42 @@
     DCHECK(index < (NSInteger)_shippingOptions.size());
     self.selectedShippingOption = _shippingOptions[index];
     _selectedItem = newlySelectedItem;
+
+    // Notify the delegate of the selection.
+    [_delegate
+        shippingOptionSelectionViewController:self
+                       selectedShippingOption:self.selectedShippingOption];
   }
-  [_delegate shippingOptionSelectionViewController:self
-                            selectedShippingOption:self.selectedShippingOption];
 }
 
 #pragma mark MDCCollectionViewStylingDelegate
 
 - (CGFloat)collectionView:(UICollectionView*)collectionView
     cellHeightAtIndexPath:(NSIndexPath*)indexPath {
-  return MDCCellDefaultTwoLineHeight;
+  CollectionViewItem* item =
+      [self.collectionViewModel itemAtIndexPath:indexPath];
+  switch (item.type) {
+    case ItemTypeMessage:
+    case ItemTypeSpinner:
+      return [MDCCollectionViewCell
+          cr_preferredHeightForWidth:CGRectGetWidth(collectionView.bounds)
+                             forItem:item];
+    case ItemTypeShippingOption:
+      return MDCCellDefaultTwoLineHeight;
+    default:
+      NOTREACHED();
+      return MDCCellDefaultOneLineHeight;
+  }
+}
+
+- (BOOL)collectionView:(UICollectionView*)collectionView
+    hidesInkViewAtIndexPath:(NSIndexPath*)indexPath {
+  NSInteger type = [self.collectionViewModel itemTypeForIndexPath:indexPath];
+  if (type == ItemTypeMessage) {
+    return YES;
+  } else {
+    return NO;
+  }
 }
 
 @end
diff --git a/ios/chrome/browser/payments/shipping_option_selection_view_controller_unittest.mm b/ios/chrome/browser/payments/shipping_option_selection_view_controller_unittest.mm
index 6da7236..403391e 100644
--- a/ios/chrome/browser/payments/shipping_option_selection_view_controller_unittest.mm
+++ b/ios/chrome/browser/payments/shipping_option_selection_view_controller_unittest.mm
@@ -2,16 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#import "ios/chrome/browser/payments/shipping_option_selection_view_controller.h"
+
 #include <vector>
 
 #include "base/mac/foundation_util.h"
-#import "ios/chrome/browser/payments/shipping_option_selection_view_controller.h"
+#import "ios/chrome/browser/payments/cells/payments_text_item.h"
+#import "ios/chrome/browser/ui/autofill/cells/status_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "ios/web/public/payments/payment_request.h"
 #include "testing/gtest/include/gtest/gtest.h"
-
 namespace {
 
 class ShippingOptionSelectionViewControllerTest
@@ -50,14 +52,43 @@
 
   ASSERT_EQ(1, NumberOfSections());
   // One item for each of shipping options.
-  EXPECT_EQ(shippingOptions.size(),
-            static_cast<unsigned int>(NumberOfItemsInSection(0)));
+  EXPECT_EQ(2U, static_cast<unsigned int>(NumberOfItemsInSection(0)));
 
-  // The first option should appear to be selected.
-  CollectionViewTextItem* item = GetCollectionViewItem(0, 0);
-  EXPECT_EQ(MDCCollectionViewCellAccessoryCheckmark, item.accessoryType);
+  // The next two items should be of type CollectionViewTextItem. The first one
+  // should appear to be selected.
+  id item = GetCollectionViewItem(0, 0);
+  ASSERT_TRUE([item isMemberOfClass:[CollectionViewTextItem class]]);
+  CollectionViewTextItem* textItem = item;
+  EXPECT_EQ(MDCCollectionViewCellAccessoryCheckmark, textItem.accessoryType);
+
   item = GetCollectionViewItem(0, 1);
-  EXPECT_EQ(MDCCollectionViewCellAccessoryNone, item.accessoryType);
+  ASSERT_TRUE([item isMemberOfClass:[CollectionViewTextItem class]]);
+  textItem = item;
+  EXPECT_EQ(MDCCollectionViewCellAccessoryNone, textItem.accessoryType);
+
+  // Test the error state.
+  [ShippingOptionSelectionController() setErrorMessage:@"Lorem ipsum"];
+  [ShippingOptionSelectionController() loadModel];
+
+  ASSERT_EQ(1, NumberOfSections());
+  // There should be 3 items now in total.
+  EXPECT_EQ(3U, static_cast<unsigned int>(NumberOfItemsInSection(0)));
+
+  // The first item should also be of type TextAndMessageItem.
+  item = GetCollectionViewItem(0, 0);
+  ASSERT_TRUE([item isMemberOfClass:[PaymentsTextItem class]]);
+
+  // Test the loading state.
+  [ShippingOptionSelectionController() setIsLoading:YES];
+  [ShippingOptionSelectionController() loadModel];
+
+  ASSERT_EQ(1, NumberOfSections());
+  // There should be only one item.
+  EXPECT_EQ(1U, static_cast<unsigned int>(NumberOfItemsInSection(0)));
+
+  // The item should be of type StatusItem.
+  item = GetCollectionViewItem(0, 0);
+  ASSERT_TRUE([item isMemberOfClass:[StatusItem class]]);
 }
 
 }  // namespace
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm
index 0311bad..dad6cbeb 100644
--- a/ios/chrome/browser/tabs/tab.mm
+++ b/ios/chrome/browser/tabs/tab.mm
@@ -1762,8 +1762,7 @@
   [self recordInterfaceOrientation];
   navigation_metrics::OriginsSeenService* originsSeenService =
       IOSChromeOriginsSeenServiceFactory::GetForBrowserState(self.browserState);
-  bool alreadySeen =
-      originsSeenService->Insert(url::Origin::Origin(lastCommittedURL));
+  bool alreadySeen = originsSeenService->Insert(url::Origin(lastCommittedURL));
   navigation_metrics::RecordMainFrameNavigation(
       lastCommittedURL, true, self.browserState->IsOffTheRecord(), alreadySeen);
 
@@ -1806,6 +1805,14 @@
   [webControllerSnapshotHelper_ setSnapshotCoalescingEnabled:NO];
 }
 
+- (void)webState:(web::WebState*)webState
+    didChangeLoadingProgress:(double)progress {
+  // TODO(crbug.com/546406): It is probably possible to do something smarter,
+  // but the fact that this is not always sent will have to be taken into
+  // account.
+  [parentTabModel_ notifyTabChanged:self];
+}
+
 - (void)webLoadCancelled:(const GURL&)url {
   // When a load is cancelled, this is the maximum that a page will ever load.
   [fullScreenController_ enableFullScreen];
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 3db83f72..f38c59b5 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -2411,15 +2411,6 @@
   };
 }
 
-- (void)webState:(web::WebState*)webState didChangeProgress:(double)progress {
-  if (webState == [_model currentTab].webState) {
-    // TODO(crbug.com/546406): It is probably possible to do something smarter,
-    // but the fact that this is not always sent will have to be taken into
-    // account.
-    [self updateToolbar];
-  }
-}
-
 - (BOOL)webState:(web::WebState*)webState
     handleContextMenu:(const web::ContextMenuParams&)params {
   // Prevent context menu from displaying for a tab which is no longer the
diff --git a/ios/chrome/browser/ui/history/history_ui_egtest.mm b/ios/chrome/browser/ui/history/history_ui_egtest.mm
index 1614bd2..789923a 100644
--- a/ios/chrome/browser/ui/history/history_ui_egtest.mm
+++ b/ios/chrome/browser/ui/history/history_ui_egtest.mm
@@ -218,14 +218,6 @@
 
 // Tests that no history is shown if there has been no navigation.
 - (void)testDisplayNoHistory {
-  // TODO(crbug.com/685570): Fix the tap instead of adding a delay.
-  GREYCondition* myCondition = [GREYCondition
-      conditionWithName:@"Delay to ensure the toolbar menu can be opened"
-                  block:^BOOL {
-                    return NO;
-                  }];
-  [myCondition waitWithTimeout:0.5];
-
   [self openHistoryPanel];
   [self assertNoHistoryShown];
 }
@@ -451,14 +443,6 @@
 
 // Navigates to history and checks elements for accessibility.
 - (void)testAccessibilityOnHistory {
-  // TODO(crbug.com/685570): Fix the tap instead of adding a delay.
-  GREYCondition* myCondition = [GREYCondition
-      conditionWithName:@"Delay to ensure the toolbar menu can be opened"
-                  block:^BOOL {
-                    return NO;
-                  }];
-  [myCondition waitWithTimeout:0.5];
-
   [self openHistoryPanel];
   chrome_test_util::VerifyAccessibilityForCurrentScreen();
   // Close history.
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn
index 9984116..6aefe9b 100644
--- a/ios/chrome/browser/ui/settings/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -144,6 +144,7 @@
     "//ios/chrome/browser/history",
     "//ios/chrome/browser/native_app_launcher:native_app_launcher_internal",
     "//ios/chrome/browser/passwords",
+    "//ios/chrome/browser/payments/cells",
     "//ios/chrome/browser/physical_web",
     "//ios/chrome/browser/prefs",
     "//ios/chrome/browser/search_engines",
diff --git a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
index 90918d7..e99d0ea4a 100644
--- a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
@@ -8,15 +8,17 @@
 
 #import "base/mac/foundation_util.h"
 #include "components/grit/components_scaled_resources.h"
+#import "ios/chrome/browser/payments/cells/payments_text_item.h"
+#import "ios/chrome/browser/payments/cells/price_item.h"
 #import "ios/chrome/browser/ui/autofill/cells/cvc_item.h"
 #import "ios/chrome/browser/ui/autofill/cells/status_item.h"
 #import "ios/chrome/browser/ui/autofill/cells/storage_switch_item.h"
-#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_account_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h"
+#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 #import "ios/chrome/browser/ui/icons/chrome_icon.h"
 #import "ios/chrome/browser/ui/settings/cells/account_control_item.h"
@@ -40,6 +42,7 @@
   SectionIdentifierSwitchCell,
   SectionIdentifierNativeAppCell,
   SectionIdentifierAutofill,
+  SectionIdentifierPayments,
   SectionIdentifierAccountCell,
   SectionIdentifierAccountControlCell,
   SectionIdentifierFooters,
@@ -63,6 +66,8 @@
   ItemTypeAccountCheckMark,
   ItemTypeAccountSignIn,
   ItemTypeApp,
+  ItemTypePaymentsSingleLine,
+  ItemTypePaymentsDynamicHeight,
   ItemTypeAutofillDynamicHeight,
   ItemTypeAutofillCVC,
   ItemTypeAutofillStatus,
@@ -217,6 +222,35 @@
   [model addItem:[self storageSwitchItem]
       toSectionWithIdentifier:SectionIdentifierAutofill];
 
+  // Payments cells.
+  [model addSectionWithIdentifier:SectionIdentifierPayments];
+  [model addItem:[self paymentsItemWithWrappingTextandOptionalImage]
+      toSectionWithIdentifier:SectionIdentifierPayments];
+  PriceItem* priceItem1 =
+      [[[PriceItem alloc] initWithType:ItemTypePaymentsSingleLine] autorelease];
+  priceItem1.item = @"Total";
+  priceItem1.notification = @"Updated";
+  priceItem1.price = @"USD $100.00";
+  [model addItem:priceItem1 toSectionWithIdentifier:SectionIdentifierPayments];
+  PriceItem* priceItem2 =
+      [[[PriceItem alloc] initWithType:ItemTypePaymentsSingleLine] autorelease];
+  priceItem2.item = @"Price label is long and should get clipped";
+  priceItem2.notification = @"Updated";
+  priceItem2.price = @"USD $1,000,000.00";
+  [model addItem:priceItem2 toSectionWithIdentifier:SectionIdentifierPayments];
+  PriceItem* priceItem3 =
+      [[[PriceItem alloc] initWithType:ItemTypePaymentsSingleLine] autorelease];
+  priceItem3.item = @"Price label is long and should get clipped";
+  priceItem3.notification = @"Should get clipped too";
+  priceItem3.price = @"USD $1,000,000.00";
+  [model addItem:priceItem3 toSectionWithIdentifier:SectionIdentifierPayments];
+  PriceItem* priceItem4 =
+      [[[PriceItem alloc] initWithType:ItemTypePaymentsSingleLine] autorelease];
+  priceItem4.item = @"Price label is long and should get clipped";
+  priceItem4.notification = @"Should get clipped too";
+  priceItem4.price = @"USD $1,000,000,000.00";
+  [model addItem:priceItem4 toSectionWithIdentifier:SectionIdentifierPayments];
+
   // Account cells.
   [model addSectionWithIdentifier:SectionIdentifierAccountCell];
   [model addItem:[self accountItemDetailWithError]
@@ -283,6 +317,7 @@
     case ItemTypeAutofillCVC:
     case ItemTypeAutofillStatus:
     case ItemTypeAutofillStorageSwitch:
+    case ItemTypePaymentsDynamicHeight:
     case ItemTypeAutofillDynamicHeight:
       return [MDCCollectionViewCell
           cr_preferredHeightForWidth:CGRectGetWidth(collectionView.bounds)
@@ -437,6 +472,15 @@
   return item;
 }
 
+- (CollectionViewItem*)paymentsItemWithWrappingTextandOptionalImage {
+  PaymentsTextItem* item = [[[PaymentsTextItem alloc]
+      initWithType:ItemTypePaymentsDynamicHeight] autorelease];
+  item.text = @"If you want to display a long text that wraps to the next line "
+              @"and may need to feature an image this is the cell to use.";
+  item.image = [UIImage imageNamed:@"app_icon_placeholder"];
+  return item;
+}
+
 - (CollectionViewItem*)autofillItemWithMainAndTrailingText {
   AutofillDataItem* item = [[[AutofillDataItem alloc]
       initWithType:ItemTypeAutofillDynamicHeight] autorelease];
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
index 7cfc951..835a55bb 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
@@ -19,6 +19,14 @@
 @implementation ChromeEarlGreyUI
 
 + (void)openToolsMenu {
+  // TODO(crbug.com/685570): Fix the tap instead of adding a delay.
+  GREYCondition* myCondition = [GREYCondition
+      conditionWithName:@"Delay to ensure the toolbar menu can be opened"
+                  block:^BOOL {
+                    return NO;
+                  }];
+  [myCondition waitWithTimeout:0.5];
+
   // TODO(crbug.com/639524): Add logic to ensure the app is in the correct
   // state, for example DCHECK if no tabs are displayed.
   [[[EarlGrey
diff --git a/ios/web/public/test/crw_mock_web_state_delegate.h b/ios/web/public/test/crw_mock_web_state_delegate.h
index bbf7bcd..51389b6 100644
--- a/ios/web/public/test/crw_mock_web_state_delegate.h
+++ b/ios/web/public/test/crw_mock_web_state_delegate.h
@@ -16,8 +16,6 @@
     const web::WebState::OpenURLParams* openURLParams;
 // web::WebState received in delegate method calls.
 @property(nonatomic, readonly) web::WebState* webState;
-// Progress received in |webState:didChangeProgress| call.
-@property(nonatomic, readonly) double changedProgress;
 // ContextMenuParams reveived in |webState:handleContextMenu:| call.
 // nullptr if that delegate method was not called.
 @property(nonatomic, readonly) web::ContextMenuParams* contextMenuParams;
diff --git a/ios/web/public/test/crw_mock_web_state_delegate.mm b/ios/web/public/test/crw_mock_web_state_delegate.mm
index 6b8b15a..f6dfa0a 100644
--- a/ios/web/public/test/crw_mock_web_state_delegate.mm
+++ b/ios/web/public/test/crw_mock_web_state_delegate.mm
@@ -17,7 +17,6 @@
 }
 
 @synthesize webState = _webState;
-@synthesize changedProgress = _changedProgress;
 @synthesize repostFormWarningRequested = _repostFormWarningRequested;
 @synthesize authenticationRequested = _authenticationRequested;
 
@@ -28,11 +27,6 @@
   return webState;
 }
 
-- (void)webState:(web::WebState*)webState didChangeProgress:(double)progress {
-  _webState = webState;
-  _changedProgress = progress;
-}
-
 - (BOOL)webState:(web::WebState*)webState
     handleContextMenu:(const web::ContextMenuParams&)params {
   _webState = webState;
diff --git a/ios/web/public/test/fakes/test_web_state_delegate.h b/ios/web/public/test/fakes/test_web_state_delegate.h
index 02b112b2..50e98d8b 100644
--- a/ios/web/public/test/fakes/test_web_state_delegate.h
+++ b/ios/web/public/test/fakes/test_web_state_delegate.h
@@ -43,7 +43,6 @@
 
   // WebStateDelegate overrides:
   JavaScriptDialogPresenter* GetJavaScriptDialogPresenter(WebState*) override;
-  void LoadProgressChanged(WebState* source, double progress) override;
   bool HandleContextMenu(WebState* source,
                          const ContextMenuParams& params) override;
   void ShowRepostFormWarningDialog(
@@ -55,11 +54,6 @@
                       NSURLCredential* proposed_credential,
                       const AuthCallback& callback) override;
 
-  // True if the WebStateDelegate LoadProgressChanged method has been called.
-  bool load_progress_changed_called() const {
-    return load_progress_changed_called_;
-  }
-
   // True if the WebStateDelegate HandleContextMenu method has been called.
   bool handle_context_menu_called() const {
     return handle_context_menu_called_;
@@ -88,7 +82,6 @@
   }
 
  private:
-  bool load_progress_changed_called_ = false;
   bool handle_context_menu_called_ = false;
   std::unique_ptr<TestRepostFormRequest> last_repost_form_request_;
   bool get_java_script_dialog_presenter_called_ = false;
diff --git a/ios/web/public/test/fakes/test_web_state_delegate.mm b/ios/web/public/test/fakes/test_web_state_delegate.mm
index 640f372..a39139c 100644
--- a/ios/web/public/test/fakes/test_web_state_delegate.mm
+++ b/ios/web/public/test/fakes/test_web_state_delegate.mm
@@ -32,10 +32,6 @@
   return &java_script_dialog_presenter_;
 }
 
-void TestWebStateDelegate::LoadProgressChanged(WebState*, double) {
-  load_progress_changed_called_ = true;
-}
-
 bool TestWebStateDelegate::HandleContextMenu(WebState*,
                                              const ContextMenuParams&) {
   handle_context_menu_called_ = true;
diff --git a/ios/web/public/web_state/web_state_delegate.h b/ios/web/public/web_state/web_state_delegate.h
index 9aefa08..8eebecc 100644
--- a/ios/web/public/web_state/web_state_delegate.h
+++ b/ios/web/public/web_state/web_state_delegate.h
@@ -28,11 +28,6 @@
   virtual WebState* OpenURLFromWebState(WebState*,
                                         const WebState::OpenURLParams&);
 
-  // Notifies the delegate that the page has made some progress loading.
-  // |progress| is a value between 0.0 (nothing loaded) to 1.0 (page fully
-  // loaded).
-  virtual void LoadProgressChanged(WebState* source, double progress);
-
   // Notifies the delegate that the user triggered the context menu with the
   // given |ContextMenuParams|. Returns true if the context menu operation was
   // handled by the delegate.
diff --git a/ios/web/public/web_state/web_state_delegate_bridge.h b/ios/web/public/web_state/web_state_delegate_bridge.h
index 155cef7d..62de0b8 100644
--- a/ios/web/public/web_state/web_state_delegate_bridge.h
+++ b/ios/web/public/web_state/web_state_delegate_bridge.h
@@ -19,10 +19,6 @@
 - (web::WebState*)webState:(web::WebState*)webState
          openURLWithParams:(const web::WebState::OpenURLParams&)params;
 
-// Called when the page has made some progress loading. |progress| is a value
-// between 0.0 (nothing loaded) to 1.0 (page fully loaded).
-- (void)webState:(web::WebState*)webState didChangeProgress:(double)progress;
-
 // Called when the user triggers the context menu with the given
 // |ContextMenuParams|. Returns YES if the context menu operation was
 // handled by the delegate. If this method is not implemented, the system
@@ -63,7 +59,6 @@
   // web::WebStateDelegate methods.
   WebState* OpenURLFromWebState(WebState*,
                                 const WebState::OpenURLParams&) override;
-  void LoadProgressChanged(WebState* source, double progress) override;
   bool HandleContextMenu(WebState* source,
                          const ContextMenuParams& params) override;
   void ShowRepostFormWarningDialog(
diff --git a/ios/web/public/web_state/web_state_observer.h b/ios/web/public/web_state/web_state_observer.h
index 53698a5..f54e88b 100644
--- a/ios/web/public/web_state/web_state_observer.h
+++ b/ios/web/public/web_state/web_state_observer.h
@@ -66,6 +66,11 @@
   // Called on history state change events.
   virtual void HistoryStateChanged() {}
 
+  // Notifies the observer that the page has made some progress loading.
+  // |progress| is a value between 0.0 (nothing loaded) to 1.0 (page fully
+  // loaded).
+  virtual void LoadProgressChanged(double progress) {}
+
   // Called on form submission. |user_initiated| is true if the user
   // interacted with the page.
   virtual void DocumentSubmitted(const std::string& form_name,
diff --git a/ios/web/public/web_state/web_state_observer_bridge.h b/ios/web/public/web_state/web_state_observer_bridge.h
index 1b88355d3..bdaf397 100644
--- a/ios/web/public/web_state/web_state_observer_bridge.h
+++ b/ios/web/public/web_state/web_state_observer_bridge.h
@@ -41,6 +41,10 @@
 // Invoked by WebStateObserverBridge::HistoryStateChanged.
 - (void)webStateDidChangeHistoryState:(web::WebState*)webState;
 
+// Invoked by WebStateObserverBridge::LoadProgressChanged.
+- (void)webState:(web::WebState*)webState
+    didChangeLoadingProgress:(double)progress;
+
 // Invoked by WebStateObserverBridge::DocumentSubmitted.
 - (void)webState:(web::WebState*)webState
     didSubmitDocumentWithFormNamed:(const std::string&)formName
@@ -98,6 +102,7 @@
   void InsterstitialDismissed() override;
   void UrlHashChanged() override;
   void HistoryStateChanged() override;
+  void LoadProgressChanged(double progress) override;
   void DocumentSubmitted(const std::string& form_name,
                          bool user_initiated) override;
   void FormActivityRegistered(const std::string& form_name,
diff --git a/ios/web/web_state/web_state_delegate.mm b/ios/web/web_state/web_state_delegate.mm
index 879e6f7..67a12bc8 100644
--- a/ios/web/web_state/web_state_delegate.mm
+++ b/ios/web/web_state/web_state_delegate.mm
@@ -24,8 +24,6 @@
   return nullptr;
 }
 
-void WebStateDelegate::LoadProgressChanged(WebState*, double) {}
-
 bool WebStateDelegate::HandleContextMenu(WebState*, const ContextMenuParams&) {
   return false;
 }
diff --git a/ios/web/web_state/web_state_delegate_bridge.mm b/ios/web/web_state/web_state_delegate_bridge.mm
index 1b80609..54d788b8 100644
--- a/ios/web/web_state/web_state_delegate_bridge.mm
+++ b/ios/web/web_state/web_state_delegate_bridge.mm
@@ -22,12 +22,6 @@
   return nullptr;
 }
 
-void WebStateDelegateBridge::LoadProgressChanged(WebState* source,
-                                                 double progress) {
-  if ([delegate_ respondsToSelector:@selector(webState:didChangeProgress:)])
-    [delegate_ webState:source didChangeProgress:progress];
-}
-
 bool WebStateDelegateBridge::HandleContextMenu(
     WebState* source,
     const ContextMenuParams& params) {
diff --git a/ios/web/web_state/web_state_delegate_bridge_unittest.mm b/ios/web/web_state/web_state_delegate_bridge_unittest.mm
index fb7d4292..45cd392 100644
--- a/ios/web/web_state/web_state_delegate_bridge_unittest.mm
+++ b/ios/web/web_state/web_state_delegate_bridge_unittest.mm
@@ -80,13 +80,6 @@
   EXPECT_EQ(params.is_renderer_initiated, result_params->is_renderer_initiated);
 }
 
-// Tests |LoadProgressChanged| forwarding.
-TEST_F(WebStateDelegateBridgeTest, LoadProgressChanged) {
-  ASSERT_EQ(0.0, [delegate_ changedProgress]);
-  bridge_->LoadProgressChanged(nullptr, 1.0);
-  EXPECT_EQ(1.0, [delegate_ changedProgress]);
-}
-
 // Tests |HandleContextMenu| forwarding.
 TEST_F(WebStateDelegateBridgeTest, HandleContextMenu) {
   EXPECT_EQ(nil, [delegate_ contextMenuParams]);
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm
index 3bbae89..7c0d609 100644
--- a/ios/web/web_state/web_state_impl.mm
+++ b/ios/web/web_state/web_state_impl.mm
@@ -442,9 +442,8 @@
 }
 
 void WebStateImpl::SendChangeLoadProgress(double progress) {
-  if (delegate_) {
-    delegate_->LoadProgressChanged(this, progress);
-  }
+  for (auto& observer : observers_)
+    observer.LoadProgressChanged(progress);
 }
 
 bool WebStateImpl::HandleContextMenu(const web::ContextMenuParams& params) {
diff --git a/ios/web/web_state/web_state_impl_unittest.mm b/ios/web/web_state/web_state_impl_unittest.mm
index 25e5bf5..c6f13ba 100644
--- a/ios/web/web_state/web_state_impl_unittest.mm
+++ b/ios/web/web_state/web_state_impl_unittest.mm
@@ -406,11 +406,6 @@
   TestWebStateDelegate delegate;
   web_state_->SetDelegate(&delegate);
 
-  // Test that LoadProgressChanged() is called.
-  EXPECT_FALSE(delegate.load_progress_changed_called());
-  web_state_->SendChangeLoadProgress(0.0);
-  EXPECT_TRUE(delegate.load_progress_changed_called());
-
   // Test that HandleContextMenu() is called.
   EXPECT_FALSE(delegate.handle_context_menu_called());
   web::ContextMenuParams context_menu_params;
diff --git a/ios/web/web_state/web_state_observer_bridge.mm b/ios/web/web_state/web_state_observer_bridge.mm
index d8621e8..198ba0d8 100644
--- a/ios/web/web_state/web_state_observer_bridge.mm
+++ b/ios/web/web_state/web_state_observer_bridge.mm
@@ -79,6 +79,12 @@
     [observer_ webStateDidChangeHistoryState:web_state()];
 }
 
+void WebStateObserverBridge::LoadProgressChanged(double progress) {
+  SEL selector = @selector(webState:didChangeLoadingProgress:);
+  if ([observer_ respondsToSelector:selector])
+    [observer_ webState:web_state() didChangeLoadingProgress:progress];
+}
+
 void WebStateObserverBridge::DocumentSubmitted(const std::string& form_name,
                                                bool user_initiated) {
   SEL selector =
diff --git a/ios/web/webui/mojo_facade.h b/ios/web/webui/mojo_facade.h
index 1d6d487..0e773088 100644
--- a/ios/web/webui/mojo_facade.h
+++ b/ios/web/webui/mojo_facade.h
@@ -6,6 +6,7 @@
 #define IOS_WEB_WEBUI_MOJO_FACADE_H_
 
 #include <map>
+#include <memory>
 #include <string>
 
 #import "base/ios/weak_nsobject.h"
@@ -132,7 +133,7 @@
   // Id of the last created watch.
   int last_watch_id_;
   // Currently active watches created through this facade.
-  std::map<int, mojo::Watcher> watchers_;
+  std::map<int, std::unique_ptr<mojo::Watcher>> watchers_;
 };
 
 }  // web
diff --git a/ios/web/webui/mojo_facade.mm b/ios/web/webui/mojo_facade.mm
index bc9b59e..6b02efb 100644
--- a/ios/web/webui/mojo_facade.mm
+++ b/ios/web/webui/mojo_facade.mm
@@ -4,12 +4,15 @@
 
 #import "ios/web/webui/mojo_facade.h"
 
+#include <utility>
+
 #import <Foundation/Foundation.h>
 
 #import "base/ios/block_types.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #import "base/mac/bind_objc_block.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 #import "ios/web/public/web_state/js/crw_js_injection_evaluator.h"
@@ -256,9 +259,9 @@
                                    callback_id, result];
     [script_evaluator_ executeJavaScript:script completionHandler:nil];
   });
-
-  mojo::Watcher& watcher = watchers_[++last_watch_id_];
-  watcher.Start(static_cast<mojo::Handle>(handle), signals, callback);
+  mojo::Watcher* watcher = new mojo::Watcher(FROM_HERE);
+  watchers_.insert(std::make_pair(++last_watch_id_, base::WrapUnique(watcher)));
+  watcher->Start(static_cast<mojo::Handle>(handle), signals, callback);
   return ValueFromInteger(last_watch_id_);
 }
 
diff --git a/ios/web_view/internal/criwv_web_view_impl.mm b/ios/web_view/internal/criwv_web_view_impl.mm
index 7c85e56..924ac2e 100644
--- a/ios/web_view/internal/criwv_web_view_impl.mm
+++ b/ios/web_view/internal/criwv_web_view_impl.mm
@@ -155,11 +155,8 @@
   }
 }
 
-// -----------------------------------------------------------------------
-// CRWWebStateDelegate implementation.
-
-- (void)webState:(web::WebState*)webState didChangeProgress:(double)progress {
-  _loadProgress = progress;
+- (void)webState:(web::WebState*)webState
+    didChangeLoadingProgress:(double)progress {
   [self notifyDidUpdateWithChanges:CRIWVWebViewUpdateTypeProgress];
 }
 
diff --git a/ipc/ipc_mojo_bootstrap.cc b/ipc/ipc_mojo_bootstrap.cc
index 7489ded..5c0b1338 100644
--- a/ipc/ipc_mojo_bootstrap.cc
+++ b/ipc/ipc_mojo_bootstrap.cc
@@ -70,6 +70,7 @@
     connector_->set_connection_error_handler(
         base::Bind(&ChannelAssociatedGroupController::OnPipeError,
                    base::Unretained(this)));
+    connector_->SetWatcherHeapProfilerTag("IPC Channel");
   }
 
   void Pause() {
diff --git a/ipc/ipc_sync_channel.cc b/ipc/ipc_sync_channel.cc
index 979c6d3..f92d1ed 100644
--- a/ipc/ipc_sync_channel.cc
+++ b/ipc/ipc_sync_channel.cc
@@ -525,7 +525,8 @@
     const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner,
     WaitableEvent* shutdown_event)
     : ChannelProxy(new SyncContext(listener, ipc_task_runner, shutdown_event)),
-      sync_handle_registry_(mojo::SyncHandleRegistry::current()) {
+      sync_handle_registry_(mojo::SyncHandleRegistry::current()),
+      dispatch_watcher_(FROM_HERE) {
   // The current (listener) thread must be distinct from the IPC thread, or else
   // sending synchronous messages will deadlock.
   DCHECK_NE(ipc_task_runner.get(), base::ThreadTaskRunnerHandle::Get().get());
@@ -641,7 +642,7 @@
 }
 
 void SyncChannel::WaitForReplyWithNestedMessageLoop(SyncContext* context) {
-  mojo::Watcher send_done_watcher;
+  mojo::Watcher send_done_watcher(FROM_HERE);
 
   ReceivedSyncMsgQueue* sync_msg_queue = context->received_sync_msgs();
   DCHECK_NE(sync_msg_queue, nullptr);
diff --git a/mash/simple_wm/simple_wm.cc b/mash/simple_wm/simple_wm.cc
index 550f5d6f..90fd986e 100644
--- a/mash/simple_wm/simple_wm.cc
+++ b/mash/simple_wm/simple_wm.cc
@@ -428,6 +428,8 @@
   return true;
 }
 
+void SimpleWM::OnWmSetCanFocus(aura::Window* window, bool can_focus) {}
+
 aura::Window* SimpleWM::OnWmCreateTopLevelWindow(
     ui::mojom::WindowType window_type,
     std::map<std::string, std::vector<uint8_t>>* properties) {
diff --git a/mash/simple_wm/simple_wm.h b/mash/simple_wm/simple_wm.h
index 6b44b568..c648897 100644
--- a/mash/simple_wm/simple_wm.h
+++ b/mash/simple_wm/simple_wm.h
@@ -77,6 +77,7 @@
       aura::Window* window,
       const std::string& name,
       std::unique_ptr<std::vector<uint8_t>>* new_data) override;
+  void OnWmSetCanFocus(aura::Window* window, bool can_focus) override;
   aura::Window* OnWmCreateTopLevelWindow(
       ui::mojom::WindowType window_type,
       std::map<std::string, std::vector<uint8_t>>* properties) override;
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn
index 7a8ea7f..ff8d8f2 100644
--- a/media/audio/BUILD.gn
+++ b/media/audio/BUILD.gn
@@ -177,8 +177,6 @@
       "win/core_audio_util_win.h",
       "win/device_enumeration_win.cc",
       "win/device_enumeration_win.h",
-      "win/wavein_input_win.cc",
-      "win/wavein_input_win.h",
       "win/waveout_output_win.cc",
       "win/waveout_output_win.h",
     ]
diff --git a/media/audio/audio_manager_unittest.cc b/media/audio/audio_manager_unittest.cc
index 7592515..7635e64 100644
--- a/media/audio/audio_manager_unittest.cc
+++ b/media/audio/audio_manager_unittest.cc
@@ -31,7 +31,6 @@
 #if defined(OS_WIN)
 #include "base/win/scoped_com_initializer.h"
 #include "media/audio/win/audio_manager_win.h"
-#include "media/audio/win/wavein_input_win.h"
 #endif
 
 #if defined(USE_PULSEAUDIO)
@@ -233,37 +232,6 @@
   AudioManagerTest() { CreateAudioManagerForTesting(); }
   ~AudioManagerTest() override {}
 
-#if defined(OS_WIN)
-  bool SetMMDeviceEnumeration() {
-    AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
-    // Windows Wave is used as default if Windows XP was detected =>
-    // return false since MMDevice is not supported on XP.
-    if (amw->enumeration_type() == AudioManagerWin::kWaveEnumeration)
-      return false;
-
-    amw->SetEnumerationType(AudioManagerWin::kMMDeviceEnumeration);
-    return true;
-  }
-
-  void SetWaveEnumeration() {
-    AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
-    amw->SetEnumerationType(AudioManagerWin::kWaveEnumeration);
-  }
-
-  std::string GetDeviceIdFromPCMWaveInAudioInputStream(
-      const std::string& device_id) {
-    AudioManagerWin* amw = static_cast<AudioManagerWin*>(audio_manager_.get());
-    AudioParameters parameters(
-        AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
-        AudioParameters::kAudioCDSampleRate, 16,
-        1024);
-    std::unique_ptr<PCMWaveInAudioInputStream> stream(
-        static_cast<PCMWaveInAudioInputStream*>(
-            amw->CreatePCMWaveInAudioInputStream(parameters, device_id)));
-    return stream.get() ? stream->device_id_ : std::string();
-  }
-#endif
-
   // Helper method which verifies that the device list starts with a valid
   // default record followed by non-default device names.
   static void CheckDeviceDescriptions(
@@ -479,11 +447,6 @@
   ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
 
   AudioDeviceDescriptions device_descriptions;
-  if (!SetMMDeviceEnumeration()) {
-    // Usage of MMDevice will fail on XP and lower.
-    LOG(WARNING) << "MM device enumeration is not supported.";
-    return;
-  }
   audio_manager_->GetAudioInputDeviceDescriptions(&device_descriptions);
   CheckDeviceDescriptions(device_descriptions);
 }
@@ -492,79 +455,9 @@
   ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
 
   AudioDeviceDescriptions device_descriptions;
-  if (!SetMMDeviceEnumeration()) {
-    // Usage of MMDevice will fail on XP and lower.
-    LOG(WARNING) << "MM device enumeration is not supported.";
-    return;
-  }
   audio_manager_->GetAudioOutputDeviceDescriptions(&device_descriptions);
   CheckDeviceDescriptions(device_descriptions);
 }
-
-// Override default enumeration API and force usage of Windows Wave.
-// This test will run on Windows XP, Windows Vista and Windows 7.
-TEST_F(AudioManagerTest, EnumerateInputDevicesWinWave) {
-  ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
-
-  AudioDeviceDescriptions device_descriptions;
-  SetWaveEnumeration();
-  audio_manager_->GetAudioInputDeviceDescriptions(&device_descriptions);
-  CheckDeviceDescriptions(device_descriptions);
-}
-
-TEST_F(AudioManagerTest, EnumerateOutputDevicesWinWave) {
-  ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
-
-  AudioDeviceDescriptions device_descriptions;
-  SetWaveEnumeration();
-  audio_manager_->GetAudioOutputDeviceDescriptions(&device_descriptions);
-  CheckDeviceDescriptions(device_descriptions);
-}
-
-TEST_F(AudioManagerTest, WinXPDeviceIdUnchanged) {
-  ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
-
-  AudioDeviceDescriptions xp_device_descriptions;
-  SetWaveEnumeration();
-  audio_manager_->GetAudioInputDeviceDescriptions(&xp_device_descriptions);
-  CheckDeviceDescriptions(xp_device_descriptions);
-
-  // Device ID should remain unchanged, including the default device ID.
-  for (const auto& description : xp_device_descriptions) {
-    EXPECT_EQ(description.unique_id,
-              GetDeviceIdFromPCMWaveInAudioInputStream(description.unique_id));
-  }
-}
-
-TEST_F(AudioManagerTest, ConvertToWinXPInputDeviceId) {
-  ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
-
-  if (!SetMMDeviceEnumeration()) {
-    // Usage of MMDevice will fail on XP and lower.
-    LOG(WARNING) << "MM device enumeration is not supported.";
-    return;
-  }
-
-  AudioDeviceDescriptions device_descriptions;
-  audio_manager_->GetAudioInputDeviceDescriptions(&device_descriptions);
-  CheckDeviceDescriptions(device_descriptions);
-
-  for (AudioDeviceDescriptions::iterator i = device_descriptions.begin();
-       i != device_descriptions.end(); ++i) {
-    std::string converted_id =
-        GetDeviceIdFromPCMWaveInAudioInputStream(i->unique_id);
-    if (i == device_descriptions.begin()) {
-      // The first in the list is the default device ID, which should not be
-      // changed when passed to PCMWaveInAudioInputStream.
-      EXPECT_EQ(i->unique_id, converted_id);
-    } else {
-      // MMDevice-style device IDs should be converted to WaveIn-style device
-      // IDs.
-      EXPECT_NE(i->unique_id, converted_id);
-    }
-  }
-}
-
 #endif  // defined(OS_WIN)
 
 #if defined(USE_PULSEAUDIO)
diff --git a/media/audio/win/audio_device_listener_win.cc b/media/audio/win/audio_device_listener_win.cc
index ebe65f4..2c2ecac 100644
--- a/media/audio/win/audio_device_listener_win.cc
+++ b/media/audio/win/audio_device_listener_win.cc
@@ -33,8 +33,8 @@
 
 AudioDeviceListenerWin::AudioDeviceListenerWin(const base::Closure& listener_cb)
     : listener_cb_(listener_cb), tick_clock_(new base::DefaultTickClock()) {
-  CHECK(CoreAudioUtil::IsSupported());
-
+  // CreateDeviceEnumerator can fail on some installations of Windows such
+  // as "Windows Server 2008 R2" where the desktop experience isn't available.
   ScopedComPtr<IMMDeviceEnumerator> device_enumerator(
       CoreAudioUtil::CreateDeviceEnumerator());
   if (!device_enumerator.get())
diff --git a/media/audio/win/audio_manager_win.cc b/media/audio/win/audio_manager_win.cc
index 4c46fc1..b5b262fb 100644
--- a/media/audio/win/audio_manager_win.cc
+++ b/media/audio/win/audio_manager_win.cc
@@ -31,7 +31,6 @@
 #include "media/audio/win/audio_low_latency_output_win.h"
 #include "media/audio/win/core_audio_util_win.h"
 #include "media/audio/win/device_enumeration_win.h"
-#include "media/audio/win/wavein_input_win.h"
 #include "media/audio/win/waveout_output_win.h"
 #include "media/base/audio_parameters.h"
 #include "media/base/bind_to_current_loop.h"
@@ -44,8 +43,18 @@
 #define DRV_QUERYDEVICEINTERFACE 0x80c
 #define DRVM_MAPPER_PREFERRED_GET 0x2015
 #define DRV_QUERYDEVICEINTERFACESIZE 0x80d
-DEFINE_GUID(AM_KSCATEGORY_AUDIO, 0x6994ad04, 0x93ef, 0x11d0,
-            0xa3, 0xcc, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96);
+DEFINE_GUID(AM_KSCATEGORY_AUDIO,
+            0x6994ad04,
+            0x93ef,
+            0x11d0,
+            0xa3,
+            0xcc,
+            0x00,
+            0xa0,
+            0xc9,
+            0x22,
+            0x31,
+            0x96);
 
 namespace media {
 
@@ -56,13 +65,6 @@
 // right drivers, but graceful error handling is needed.
 static const int kWinMaxChannels = 8;
 
-// We use 3 buffers for recording audio so that if a recording callback takes
-// some time to return we won't lose audio. More buffers while recording are
-// ok because they don't introduce any delay in recording, unlike in playback
-// where you first need to fill in that number of buffers before starting to
-// play.
-static const int kNumInputBuffers = 3;
-
 // Buffer size to use for input and output stream when a proper size can't be
 // determined from the system
 static const int kFallbackBufferSize = 2048;
@@ -94,7 +96,8 @@
     if (SetupDiEnumDriverInfo(device_info, device_data, SPDIT_COMPATDRIVER, 0,
                               &driver_data)) {
       DWORDLONG version = driver_data.DriverVersion;
-      device_and_driver_info = base::string16(driver_data.Description) + L" v" +
+      device_and_driver_info =
+          base::string16(driver_data.Description) + L" v" +
           base::IntToString16(GetVersionPartAsInt((version >> 48))) + L"." +
           base::IntToString16(GetVersionPartAsInt((version >> 32))) + L"." +
           base::IntToString16(GetVersionPartAsInt((version >> 16))) + L"." +
@@ -134,13 +137,13 @@
     AudioLogFactory* audio_log_factory)
     : AudioManagerBase(std::move(task_runner),
                        std::move(worker_task_runner),
-                       audio_log_factory),
-      // |CoreAudioUtil::IsSupported()| uses static variables to avoid doing
-      // multiple initializations.  This is however not thread safe.
-      // So, here we call it explicitly before we kick off the audio thread
-      // or do any other work.
-      enumeration_type_(CoreAudioUtil::IsSupported() ? kMMDeviceEnumeration
-                                                     : kWaveEnumeration) {
+                       audio_log_factory) {
+  // |CoreAudioUtil::IsSupported()| uses static variables to avoid doing
+  // multiple initializations.  This is however not thread safe.
+  // So, here we call it explicitly before we kick off the audio thread
+  // or do any other work.
+  CoreAudioUtil::IsSupported();
+
   SetMaxOutputStreamsAllowed(kMaxOutputStreams);
 
   // WARNING: This is executed on the UI loop, do not add any code here which
@@ -149,8 +152,9 @@
 
   // Task must be posted last to avoid races from handing out "this" to the
   // audio thread.
-  GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
-      &AudioManagerWin::InitializeOnAudioThread, base::Unretained(this)));
+  GetTaskRunner()->PostTask(
+      FROM_HERE, base::Bind(&AudioManagerWin::InitializeOnAudioThread,
+                            base::Unretained(this)));
 }
 
 AudioManagerWin::~AudioManagerWin() {
@@ -168,13 +172,10 @@
 void AudioManagerWin::InitializeOnAudioThread() {
   DCHECK(GetTaskRunner()->BelongsToCurrentThread());
 
-  if (core_audio_supported()) {
-    // AudioDeviceListenerWin must be initialized on a COM thread and should
-    // only be used if WASAPI / Core Audio is supported.
-    output_device_listener_.reset(new AudioDeviceListenerWin(BindToCurrentLoop(
-        base::Bind(&AudioManagerWin::NotifyAllOutputDeviceChangeListeners,
-                   base::Unretained(this)))));
-  }
+  // AudioDeviceListenerWin must be initialized on a COM thread.
+  output_device_listener_.reset(new AudioDeviceListenerWin(BindToCurrentLoop(
+      base::Bind(&AudioManagerWin::NotifyAllOutputDeviceChangeListeners,
+                 base::Unretained(this)))));
 }
 
 base::string16 AudioManagerWin::GetAudioInputDeviceModel() {
@@ -193,10 +194,9 @@
     return base::string16();  // No audio capture device.
 
   base::string16 device_interface_name;
-  base::string16::value_type* name_ptr = base::WriteInto(&device_interface_name,
-      device_interface_name_size / bytes_in_char16);
-  waveInMessage(reinterpret_cast<HWAVEIN>(device_id),
-                DRV_QUERYDEVICEINTERFACE,
+  base::string16::value_type* name_ptr = base::WriteInto(
+      &device_interface_name, device_interface_name_size / bytes_in_char16);
+  waveInMessage(reinterpret_cast<HWAVEIN>(device_id), DRV_QUERYDEVICEINTERFACE,
                 reinterpret_cast<DWORD_PTR>(name_ptr),
                 static_cast<DWORD_PTR>(device_interface_name_size));
 
@@ -227,10 +227,9 @@
         reinterpret_cast<SP_DEVICE_INTERFACE_DETAIL_DATA*>(
             interface_detail_buffer.get());
     interface_detail->cbSize = interface_detail_size;
-    if (!SetupDiGetDeviceInterfaceDetail(device_info, &interface_data,
-                                         interface_detail,
-                                         interface_detail_size, NULL,
-                                         &device_data))
+    if (!SetupDiGetDeviceInterfaceDetail(
+            device_info, &interface_data, interface_detail,
+            interface_detail_size, NULL, &device_data))
       return base::string16();
 
     bool device_found = (device_interface_name == interface_detail->DevicePath);
@@ -243,46 +242,25 @@
 }
 
 void AudioManagerWin::ShowAudioInputSettings() {
-  std::wstring program;
-  std::string argument;
-  if (!core_audio_supported()) {
-    program = L"sndvol32.exe";
-    argument = "-R";
-  } else {
-    program = L"control.exe";
-    argument = "mmsys.cpl,,1";
-  }
-
   base::FilePath path;
   PathService::Get(base::DIR_SYSTEM, &path);
-  path = path.Append(program);
+  path = path.Append(L"control.exe");
   base::CommandLine command_line(path);
-  command_line.AppendArg(argument);
+  command_line.AppendArg("mmsys.cpl,,1");
   base::LaunchProcess(command_line, base::LaunchOptions());
 }
 
-void AudioManagerWin::GetAudioDeviceNamesImpl(
-    bool input,
-    AudioDeviceNames* device_names) {
+void AudioManagerWin::GetAudioDeviceNamesImpl(bool input,
+                                              AudioDeviceNames* device_names) {
   DCHECK(device_names->empty());
   // Enumerate all active audio-endpoint capture devices.
-  if (enumeration_type() == kWaveEnumeration) {
-    // Utilize the Wave API for Windows XP.
-    if (input)
-      GetInputDeviceNamesWinXP(device_names);
-    else
-      GetOutputDeviceNamesWinXP(device_names);
-  } else {
-    // Utilize the MMDevice API (part of Core Audio) for Vista and higher.
-    if (input)
-      GetInputDeviceNamesWin(device_names);
-    else
-      GetOutputDeviceNamesWin(device_names);
-  }
+  if (input)
+    GetInputDeviceNamesWin(device_names);
+  else
+    GetOutputDeviceNamesWin(device_names);
 
   if (!device_names->empty()) {
-    if (enumeration_type() == kMMDeviceEnumeration)
-      device_names->push_front(AudioDeviceName::CreateCommunications());
+    device_names->push_front(AudioDeviceName::CreateCommunications());
 
     // Always add default device parameters as first element.
     device_names->push_front(AudioDeviceName::CreateDefault());
@@ -300,18 +278,14 @@
 
 AudioParameters AudioManagerWin::GetInputStreamParameters(
     const std::string& device_id) {
-  HRESULT hr = E_FAIL;
   AudioParameters parameters;
-  if (core_audio_supported()) {
-    hr = CoreAudioUtil::GetPreferredAudioParameters(device_id, false,
-                                                    &parameters);
-  }
+  HRESULT hr =
+      CoreAudioUtil::GetPreferredAudioParameters(device_id, false, &parameters);
 
   if (FAILED(hr) || !parameters.IsValid()) {
-    // Windows Wave implementation is being used.
-    parameters =
-        AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
-                        CHANNEL_LAYOUT_STEREO, 48000, 16, kFallbackBufferSize);
+    LOG(WARNING) << "Unable to get preferred audio params for " << device_id
+                 << " 0x" << std::hex << hr;
+    return parameters;
   }
 
   int user_buffer_size = GetUserBufferSize();
@@ -323,11 +297,6 @@
 
 std::string AudioManagerWin::GetAssociatedOutputDeviceID(
     const std::string& input_device_id) {
-  if (!core_audio_supported()) {
-    NOTIMPLEMENTED()
-        << "GetAssociatedOutputDeviceID is not supported on this OS";
-    return std::string();
-  }
   return CoreAudioUtil::GetMatchingOutputDeviceID(input_device_id);
 }
 
@@ -345,9 +314,7 @@
   if (params.channels() > kWinMaxChannels)
     return NULL;
 
-  return new PCMWaveOutAudioOutputStream(this,
-                                         params,
-                                         NumberOfWaveOutBuffers(),
+  return new PCMWaveOutAudioOutputStream(this, params, NumberOfWaveOutBuffers(),
                                          WAVE_MAPPER);
 }
 
@@ -364,16 +331,6 @@
   if (params.channels() > kWinMaxChannels)
     return NULL;
 
-  if (!core_audio_supported()) {
-    // Fall back to Windows Wave implementation on Windows XP or lower.
-    DLOG_IF(ERROR, !device_id.empty() &&
-                       device_id != AudioDeviceDescription::kDefaultDeviceId)
-        << "Opening by device id not supported by PCMWaveOutAudioOutputStream";
-    DVLOG(1) << "Using WaveOut since WASAPI requires at least Vista.";
-    return new PCMWaveOutAudioOutputStream(
-        this, params, NumberOfWaveOutBuffers(), WAVE_MAPPER);
-  }
-
   // Pass an empty string to indicate that we want the default device
   // since we consistently only check for an empty string in
   // WASAPIAudioOutputStream.
@@ -394,7 +351,7 @@
     const std::string& device_id,
     const LogCallback& log_callback) {
   DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format());
-  return CreatePCMWaveInAudioInputStream(params, device_id);
+  return MakeLowLatencyInputStream(params, device_id, log_callback);
 }
 
 // Factory for the implementations of AudioInputStream for
@@ -403,81 +360,67 @@
     const AudioParameters& params,
     const std::string& device_id,
     const LogCallback& log_callback) {
-  DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format());
+  // Used for both AUDIO_PCM_LOW_LATENCY and AUDIO_PCM_LINEAR.
   DVLOG(1) << "MakeLowLatencyInputStream: " << device_id;
-  AudioInputStream* stream = NULL;
-  UMA_HISTOGRAM_BOOLEAN("Media.WindowsCoreAudioInput", core_audio_supported());
-  if (!core_audio_supported()) {
-    // Fall back to Windows Wave implementation on Windows XP or lower.
-    DVLOG(1) << "Using WaveIn since WASAPI requires at least Vista.";
-    stream = CreatePCMWaveInAudioInputStream(params, device_id);
-  } else {
-    stream = new WASAPIAudioInputStream(this, params, device_id);
-  }
-
-  return stream;
+  return new WASAPIAudioInputStream(this, params, device_id);
 }
 
 std::string AudioManagerWin::GetDefaultOutputDeviceID() {
-  if (!core_audio_supported())
-    return std::string();
   return CoreAudioUtil::GetDefaultOutputDeviceID();
 }
 
 AudioParameters AudioManagerWin::GetPreferredOutputStreamParameters(
     const std::string& output_device_id,
     const AudioParameters& input_params) {
-  DLOG_IF(ERROR, !core_audio_supported() && !output_device_id.empty())
-      << "CoreAudio is required to open non-default devices.";
-
   const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
   ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
   int sample_rate = 48000;
   int buffer_size = kFallbackBufferSize;
   int bits_per_sample = 16;
   int effects = AudioParameters::NO_EFFECTS;
-  bool use_input_params = !core_audio_supported();
-  if (core_audio_supported()) {
-    if (cmd_line->HasSwitch(switches::kEnableExclusiveAudio)) {
-      // TODO(rtoy): tune these values for best possible WebAudio
-      // performance. WebRTC works well at 48kHz and a buffer size of 480
-      // samples will be used for this case. Note that exclusive mode is
-      // experimental. This sample rate will be combined with a buffer size of
-      // 256 samples, which corresponds to an output delay of ~5.33ms.
-      sample_rate = 48000;
-      buffer_size = 256;
-      if (input_params.IsValid())
-        channel_layout = input_params.channel_layout();
-    } else {
-      AudioParameters params;
-      HRESULT hr = CoreAudioUtil::GetPreferredAudioParameters(
-          output_device_id.empty() ? GetDefaultOutputDeviceID()
-                                   : output_device_id,
-          true, &params);
-      if (SUCCEEDED(hr)) {
-        bits_per_sample = params.bits_per_sample();
-        buffer_size = params.frames_per_buffer();
-        channel_layout = params.channel_layout();
-        sample_rate = params.sample_rate();
-        effects = params.effects();
-      } else {
-        // TODO(tommi): This should never happen really and I'm not sure that
-        // setting use_input_params is the right thing to do since WASAPI i
-        // definitely supported (see  core_audio_supported() above) and
-        // |use_input_params| is only for cases when it isn't supported.
-        DLOG(ERROR) << "GetPreferredAudioParameters failed: " << std::hex << hr;
-        use_input_params = true;
-      }
+
+  // TODO(henrika): Remove kEnableExclusiveAudio and related code. It doesn't
+  // look like it's used.
+  if (cmd_line->HasSwitch(switches::kEnableExclusiveAudio)) {
+    // TODO(rtoy): tune these values for best possible WebAudio
+    // performance. WebRTC works well at 48kHz and a buffer size of 480
+    // samples will be used for this case. Note that exclusive mode is
+    // experimental. This sample rate will be combined with a buffer size of
+    // 256 samples, which corresponds to an output delay of ~5.33ms.
+    sample_rate = 48000;
+    buffer_size = 256;
+    if (input_params.IsValid())
+      channel_layout = input_params.channel_layout();
+  } else {
+    AudioParameters params;
+    HRESULT hr = CoreAudioUtil::GetPreferredAudioParameters(
+        output_device_id.empty() ? GetDefaultOutputDeviceID()
+                                 : output_device_id,
+        true, &params);
+    if (FAILED(hr)) {
+      // This can happen when CoreAudio isn't supported or available
+      // (e.g. certain installations of Windows Server 2008 R2).
+      // Instead of returning the input_params, we'll return invalid
+      // AudioParameters to make sure that an attempt to create this output
+      // stream, won't succeed. This behavior is also consistent with
+      // GetInputStreamParameters.
+      DLOG(ERROR) << "GetPreferredAudioParameters failed: " << std::hex << hr;
+      return AudioParameters();
     }
+
+    bits_per_sample = params.bits_per_sample();
+    buffer_size = params.frames_per_buffer();
+    channel_layout = params.channel_layout();
+    sample_rate = params.sample_rate();
+    effects = params.effects();
   }
 
   if (input_params.IsValid()) {
     // If the user has enabled checking supported channel layouts or we don't
     // have a valid channel layout yet, try to use the input layout.  See bugs
     // http://crbug.com/259165 and http://crbug.com/311906 for more details.
-    if (core_audio_supported() &&
-        (cmd_line->HasSwitch(switches::kTrySupportedChannelLayouts) ||
-         channel_layout == CHANNEL_LAYOUT_UNSUPPORTED)) {
+    if (cmd_line->HasSwitch(switches::kTrySupportedChannelLayouts) ||
+        channel_layout == CHANNEL_LAYOUT_UNSUPPORTED) {
       // Check if it is possible to open up at the specified input channel
       // layout but avoid checking if the specified layout is the same as the
       // hardware (preferred) layout. We do this extra check to avoid the
@@ -501,17 +444,6 @@
     }
 
     effects |= input_params.effects();
-    if (use_input_params) {
-      // If WASAPI isn't supported we'll fallback to WaveOut, which will take
-      // care of resampling and bits per sample changes.  By setting these
-      // equal to the input values, AudioOutputResampler will skip resampling
-      // and bit per sample differences (since the input parameters will match
-      // the output parameters).
-      bits_per_sample = input_params.bits_per_sample();
-      buffer_size = input_params.frames_per_buffer();
-      channel_layout = input_params.channel_layout();
-      sample_rate = input_params.sample_rate();
-    }
   }
 
   int user_buffer_size = GetUserBufferSize();
@@ -524,25 +456,7 @@
   return params;
 }
 
-AudioInputStream* AudioManagerWin::CreatePCMWaveInAudioInputStream(
-    const AudioParameters& params,
-    const std::string& device_id) {
-  std::string xp_device_id = device_id;
-  if (device_id != AudioDeviceDescription::kDefaultDeviceId &&
-      enumeration_type_ == kMMDeviceEnumeration) {
-    xp_device_id = ConvertToWinXPInputDeviceId(device_id);
-    if (xp_device_id.empty()) {
-      DLOG(ERROR) << "Cannot find a waveIn device which matches the device ID "
-                  << device_id;
-      return NULL;
-    }
-  }
-
-  return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers,
-                                       xp_device_id);
-}
-
-/// static
+// static
 ScopedAudioManagerPtr CreateAudioManager(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
diff --git a/media/audio/win/audio_manager_win.h b/media/audio/win/audio_manager_win.h
index 5a5395c3..c315c81 100644
--- a/media/audio/win/audio_manager_win.h
+++ b/media/audio/win/audio_manager_win.h
@@ -64,33 +64,9 @@
       const AudioParameters& input_params) override;
 
  private:
-  enum EnumerationType {
-    kMMDeviceEnumeration,
-    kWaveEnumeration,
-  };
-
   // Allow unit test to modify the utilized enumeration API.
   friend class AudioManagerTest;
 
-  EnumerationType enumeration_type_;
-  EnumerationType enumeration_type() { return enumeration_type_; }
-  void SetEnumerationType(EnumerationType type) {
-    enumeration_type_ = type;
-  }
-
-  inline bool core_audio_supported() const {
-    return enumeration_type_ == kMMDeviceEnumeration;
-  }
-
-  // Returns a PCMWaveInAudioInputStream instance or NULL on failure.
-  // This method converts MMDevice-style device ID to WaveIn-style device ID if
-  // necessary.
-  // (Please see device_enumeration_win.h for more info about the two kinds of
-  // device IDs.)
-  AudioInputStream* CreatePCMWaveInAudioInputStream(
-      const AudioParameters& params,
-      const std::string& device_id);
-
   // Helper methods for performing expensive initialization tasks on the audio
   // thread instead of on the UI thread which AudioManager is constructed on.
   void InitializeOnAudioThread();
diff --git a/media/audio/win/core_audio_util_win.cc b/media/audio/win/core_audio_util_win.cc
index cb21af6..0f8cdb2 100644
--- a/media/audio/win/core_audio_util_win.cc
+++ b/media/audio/win/core_audio_util_win.cc
@@ -259,7 +259,6 @@
 }
 
 int CoreAudioUtil::NumberOfActiveDevices(EDataFlow data_flow) {
-  DCHECK(IsSupported());
   // Create the IMMDeviceEnumerator interface.
   ScopedComPtr<IMMDeviceEnumerator> device_enumerator =
       CreateDeviceEnumerator();
@@ -287,16 +286,11 @@
 }
 
 ScopedComPtr<IMMDeviceEnumerator> CoreAudioUtil::CreateDeviceEnumerator() {
-  DCHECK(IsSupported());
-  ScopedComPtr<IMMDeviceEnumerator> device_enumerator =
-      CreateDeviceEnumeratorInternal(true);
-  CHECK(device_enumerator);
-  return device_enumerator;
+  return CreateDeviceEnumeratorInternal(true);
 }
 
 ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDefaultDevice(EDataFlow data_flow,
                                                            ERole role) {
-  DCHECK(IsSupported());
   ScopedComPtr<IMMDevice> endpoint_device;
 
   // Create the IMMDeviceEnumerator interface.
@@ -326,14 +320,12 @@
 }
 
 std::string CoreAudioUtil::GetDefaultOutputDeviceID() {
-  DCHECK(IsSupported());
   ScopedComPtr<IMMDevice> device(CreateDefaultDevice(eRender, eConsole));
   return device.get() ? GetDeviceID(device.get()) : std::string();
 }
 
 ScopedComPtr<IMMDevice> CoreAudioUtil::CreateDevice(
     const std::string& device_id) {
-  DCHECK(IsSupported());
   ScopedComPtr<IMMDevice> endpoint_device;
 
   // Create the IMMDeviceEnumerator interface.
@@ -364,8 +356,6 @@
 }
 
 HRESULT CoreAudioUtil::GetDeviceName(IMMDevice* device, AudioDeviceName* name) {
-  DCHECK(IsSupported());
-
   // Retrieve unique name of endpoint device.
   // Example: "{0.0.1.00000000}.{8db6020f-18e3-4f25-b6f5-7726c9122574}".
   AudioDeviceName device_name;
@@ -385,8 +375,6 @@
 
 std::string CoreAudioUtil::GetAudioControllerID(IMMDevice* device,
     IMMDeviceEnumerator* enumerator) {
-  DCHECK(IsSupported());
-
   // Fetching the controller device id could be as simple as fetching the value
   // of the "{B3F8FA53-0004-438E-9003-51A46E139BFC},2" property in the property
   // store of the |device|, but that key isn't defined in any header and
@@ -485,7 +473,6 @@
 }
 
 std::string CoreAudioUtil::GetFriendlyName(const std::string& device_id) {
-  DCHECK(IsSupported());
   ScopedComPtr<IMMDevice> audio_device = CreateDevice(device_id);
   if (!audio_device.get())
     return std::string();
@@ -501,7 +488,6 @@
 bool CoreAudioUtil::DeviceIsDefault(EDataFlow flow,
                                     ERole role,
                                     const std::string& device_id) {
-  DCHECK(IsSupported());
   ScopedComPtr<IMMDevice> device = CreateDefaultDevice(flow, role);
   if (!device.get())
     return false;
@@ -511,7 +497,6 @@
 }
 
 EDataFlow CoreAudioUtil::GetDataFlow(IMMDevice* device) {
-  DCHECK(IsSupported());
   ScopedComPtr<IMMEndpoint> endpoint;
   HRESULT hr = device->QueryInterface(endpoint.Receive());
   if (FAILED(hr)) {
@@ -530,8 +515,6 @@
 
 ScopedComPtr<IAudioClient> CoreAudioUtil::CreateClient(
     IMMDevice* audio_device) {
-  DCHECK(IsSupported());
-
   // Creates and activates an IAudioClient COM object given the selected
   // endpoint device.
   ScopedComPtr<IAudioClient> audio_client;
@@ -545,7 +528,6 @@
 
 ScopedComPtr<IAudioClient> CoreAudioUtil::CreateDefaultClient(
     EDataFlow data_flow, ERole role) {
-  DCHECK(IsSupported());
   ScopedComPtr<IMMDevice> default_device(CreateDefaultDevice(data_flow, role));
   return (default_device.get() ? CreateClient(default_device.get())
                                : ScopedComPtr<IAudioClient>());
@@ -565,7 +547,6 @@
 
 HRESULT CoreAudioUtil::GetSharedModeMixFormat(
     IAudioClient* client, WAVEFORMATPCMEX* format) {
-  DCHECK(IsSupported());
   ScopedCoMem<WAVEFORMATPCMEX> format_pcmex;
   HRESULT hr = client->GetMixFormat(
       reinterpret_cast<WAVEFORMATEX**>(&format_pcmex));
@@ -584,7 +565,6 @@
 bool CoreAudioUtil::IsFormatSupported(IAudioClient* client,
                                       AUDCLNT_SHAREMODE share_mode,
                                       const WAVEFORMATPCMEX* format) {
-  DCHECK(IsSupported());
   ScopedCoMem<WAVEFORMATEXTENSIBLE> closest_match;
   HRESULT hr = client->IsFormatSupported(
       share_mode, reinterpret_cast<const WAVEFORMATEX*>(format),
@@ -606,10 +586,7 @@
                                              EDataFlow data_flow,
                                              ERole role,
                                              ChannelLayout channel_layout) {
-  DCHECK(IsSupported());
-
   // First, get the preferred mixing format for shared mode streams.
-
   ScopedComPtr<IAudioClient> client(CreateClient(device_id, data_flow, role));
   if (!client.get())
     return false;
@@ -655,8 +632,6 @@
 HRESULT CoreAudioUtil::GetDevicePeriod(IAudioClient* client,
                                        AUDCLNT_SHAREMODE share_mode,
                                        REFERENCE_TIME* device_period) {
-  DCHECK(IsSupported());
-
   // Get the period of the engine thread.
   REFERENCE_TIME default_period = 0;
   REFERENCE_TIME minimum_period = 0;
@@ -674,7 +649,6 @@
 
 HRESULT CoreAudioUtil::GetPreferredAudioParameters(
     IAudioClient* client, AudioParameters* params) {
-  DCHECK(IsSupported());
   WAVEFORMATPCMEX mix_format;
   HRESULT hr = GetSharedModeMixFormat(client, &mix_format);
   if (FAILED(hr))
@@ -741,8 +715,6 @@
 HRESULT CoreAudioUtil::GetPreferredAudioParameters(const std::string& device_id,
                                                    bool is_output_device,
                                                    AudioParameters* params) {
-  DCHECK(IsSupported());
-
   ScopedComPtr<IMMDevice> device;
   if (device_id == AudioDeviceDescription::kDefaultDeviceId) {
     device = CoreAudioUtil::CreateDefaultDevice(
@@ -806,8 +778,6 @@
                                             HANDLE event_handle,
                                             uint32_t* endpoint_buffer_size,
                                             const GUID* session_guid) {
-  DCHECK(IsSupported());
-
   // Use default flags (i.e, dont set AUDCLNT_STREAMFLAGS_NOPERSIST) to
   // ensure that the volume level and muting state for a rendering session
   // are persistent across system restarts. The volume level and muting
@@ -865,8 +835,6 @@
 
 ScopedComPtr<IAudioRenderClient> CoreAudioUtil::CreateRenderClient(
     IAudioClient* client) {
-  DCHECK(IsSupported());
-
   // Get access to the IAudioRenderClient interface. This interface
   // enables us to write output data to a rendering endpoint buffer.
   ScopedComPtr<IAudioRenderClient> audio_render_client;
@@ -881,8 +849,6 @@
 
 ScopedComPtr<IAudioCaptureClient> CoreAudioUtil::CreateCaptureClient(
     IAudioClient* client) {
-  DCHECK(IsSupported());
-
   // Get access to the IAudioCaptureClient interface. This interface
   // enables us to read input data from a capturing endpoint buffer.
   ScopedComPtr<IAudioCaptureClient> audio_capture_client;
@@ -897,8 +863,6 @@
 
 bool CoreAudioUtil::FillRenderEndpointBufferWithSilence(
     IAudioClient* client, IAudioRenderClient* render_client) {
-  DCHECK(IsSupported());
-
   UINT32 endpoint_buffer_size = 0;
   if (FAILED(client->GetBufferSize(&endpoint_buffer_size)))
     return false;
diff --git a/media/audio/win/device_enumeration_win.cc b/media/audio/win/device_enumeration_win.cc
index 596389c..b333204 100644
--- a/media/audio/win/device_enumeration_win.cc
+++ b/media/audio/win/device_enumeration_win.cc
@@ -7,21 +7,20 @@
 #include <Functiondiscoverykeys_devpkey.h>  // MMDeviceAPI.h must come first
 #include <stddef.h>
 
-#include "media/audio/win/audio_manager_win.h"
-
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/scoped_co_mem.h"
 #include "base/win/scoped_comptr.h"
 #include "base/win/scoped_propvariant.h"
+#include "media/audio/win/audio_manager_win.h"
 
 using base::win::ScopedComPtr;
 using base::win::ScopedCoMem;
 
 // Taken from Mmddk.h.
-#define DRV_RESERVED                      0x0800
-#define DRV_QUERYFUNCTIONINSTANCEID       (DRV_RESERVED + 17)
-#define DRV_QUERYFUNCTIONINSTANCEIDSIZE   (DRV_RESERVED + 18)
+#define DRV_RESERVED 0x0800
+#define DRV_QUERYFUNCTIONINSTANCEID (DRV_RESERVED + 17)
+#define DRV_QUERYFUNCTIONINSTANCEIDSIZE (DRV_RESERVED + 18)
 
 namespace media {
 
@@ -41,8 +40,7 @@
   // Generate a collection of active audio endpoint devices.
   // This method will succeed even if all devices are disabled.
   ScopedComPtr<IMMDeviceCollection> collection;
-  hr = enumerator->EnumAudioEndpoints(data_flow,
-                                      DEVICE_STATE_ACTIVE,
+  hr = enumerator->EnumAudioEndpoints(data_flow, DEVICE_STATE_ACTIVE,
                                       collection.Receive());
   if (FAILED(hr))
     return false;
@@ -81,8 +79,8 @@
                                 friendly_name.Receive());
 
       // Store the user-friendly name.
-      if (SUCCEEDED(hr) &&
-          friendly_name.get().vt == VT_LPWSTR && friendly_name.get().pwszVal) {
+      if (SUCCEEDED(hr) && friendly_name.get().vt == VT_LPWSTR &&
+          friendly_name.get().pwszVal) {
         device.device_name = base::WideToUTF8(friendly_name.get().pwszVal);
       }
     }
@@ -99,9 +97,9 @@
 // devices. We deal with this by implementing the logic as a templated
 // function that takes the functions and struct type to use as
 // template parameters.
-template <UINT (__stdcall *NumDevsFunc)(),
+template <UINT(__stdcall* NumDevsFunc)(),
           typename CAPSSTRUCT,
-          MMRESULT (__stdcall *DevCapsFunc)(UINT_PTR, CAPSSTRUCT*, UINT)>
+          MMRESULT(__stdcall* DevCapsFunc)(UINT_PTR, CAPSSTRUCT*, UINT)>
 static bool GetDeviceNamesWinXPImpl(AudioDeviceNames* device_names) {
   // Retrieve the number of active waveform input devices.
   UINT number_of_active_devices = NumDevsFunc();
@@ -118,7 +116,7 @@
   // there is no safe method to retrieve a unique device name on XP.
   for (UINT i = 0; i < number_of_active_devices; ++i) {
     // Retrieve the capabilities of the specified waveform-audio input device.
-    err = DevCapsFunc(i,  &capabilities, sizeof(capabilities));
+    err = DevCapsFunc(i, &capabilities, sizeof(capabilities));
     if (err != MMSYSERR_NOERROR)
       continue;
 
@@ -146,60 +144,13 @@
 }
 
 bool GetInputDeviceNamesWinXP(AudioDeviceNames* device_names) {
-  return GetDeviceNamesWinXPImpl<
-      waveInGetNumDevs, WAVEINCAPSW, waveInGetDevCapsW>(device_names);
+  return GetDeviceNamesWinXPImpl<waveInGetNumDevs, WAVEINCAPSW,
+                                 waveInGetDevCapsW>(device_names);
 }
 
 bool GetOutputDeviceNamesWinXP(AudioDeviceNames* device_names) {
-  return GetDeviceNamesWinXPImpl<
-      waveOutGetNumDevs, WAVEOUTCAPSW, waveOutGetDevCapsW>(device_names);
-}
-
-std::string ConvertToWinXPInputDeviceId(const std::string& device_id) {
-  UINT number_of_active_devices = waveInGetNumDevs();
-  MMRESULT result = MMSYSERR_NOERROR;
-
-  UINT i = 0;
-  for (; i < number_of_active_devices; ++i) {
-    size_t size = 0;
-    // Get the size (including the terminating NULL) of the endpoint ID of the
-    // waveIn device.
-    result = waveInMessage(reinterpret_cast<HWAVEIN>(i),
-                           DRV_QUERYFUNCTIONINSTANCEIDSIZE,
-                           reinterpret_cast<DWORD_PTR>(&size), NULL);
-    if (result != MMSYSERR_NOERROR)
-      continue;
-
-    ScopedCoMem<WCHAR> id;
-    id.Reset(static_cast<WCHAR*>(CoTaskMemAlloc(size)));
-    if (!id)
-      continue;
-
-    // Get the endpoint ID string for this waveIn device.
-    result = waveInMessage(
-        reinterpret_cast<HWAVEIN>(i), DRV_QUERYFUNCTIONINSTANCEID,
-        reinterpret_cast<DWORD_PTR>(static_cast<WCHAR*>(id)), size);
-    if (result != MMSYSERR_NOERROR)
-      continue;
-
-    std::string utf8_id = base::WideToUTF8(static_cast<WCHAR*>(id));
-    // Check whether the endpoint ID string of this waveIn device matches that
-    // of the audio endpoint device.
-    if (device_id == utf8_id)
-      break;
-  }
-
-  // If a matching waveIn device was found, convert the unique endpoint ID
-  // string to a standard friendly name with max 32 characters.
-  if (i < number_of_active_devices) {
-    WAVEINCAPS capabilities;
-
-    result = waveInGetDevCaps(i, &capabilities, sizeof(capabilities));
-    if (result == MMSYSERR_NOERROR)
-      return base::WideToUTF8(capabilities.szPname);
-  }
-
-  return std::string();
+  return GetDeviceNamesWinXPImpl<waveOutGetNumDevs, WAVEOUTCAPSW,
+                                 waveOutGetDevCapsW>(device_names);
 }
 
 }  // namespace media
diff --git a/media/audio/win/device_enumeration_win.h b/media/audio/win/device_enumeration_win.h
index e61a3318..681bf59e 100644
--- a/media/audio/win/device_enumeration_win.h
+++ b/media/audio/win/device_enumeration_win.h
@@ -21,23 +21,14 @@
 bool GetInputDeviceNamesWin(media::AudioDeviceNames* device_names);
 bool GetOutputDeviceNamesWin(media::AudioDeviceNames* device_names);
 
-// Returns a list of audio input or output device structures (name and
+// Returns a list of audio output device structures (name and
 // unique device ID) using the WaveIn API which is supported on
 // Windows XP and higher.
 // Example record in the output list:
 // - device_name: "Microphone (Realtek High Defini".
 // - unique_id: "Microphone (Realtek High Defini" (same as friendly name).
-bool GetInputDeviceNamesWinXP(media::AudioDeviceNames* device_names);
 bool GetOutputDeviceNamesWinXP(media::AudioDeviceNames* device_names);
 
-// Converts an input device ID generated by |GetInputDeviceNamesWin()| to the
-// corresponding ID by |GetInputDeviceNamesWinXP()|. Returns an empty string on
-// failure.
-// Example input and output:
-// - input ID: "{0.0.1.00000000}.{8db6020f-18e3-4f25-b6f5-7726c9122574}"
-// - output ID: "Microphone (Realtek High Defini"
-std::string ConvertToWinXPInputDeviceId(const std::string& device_id);
-
 }  // namespace media
 
 #endif  // MEDIA_AUDIO_WIN_DEVICE_ENUMERATION_WIN_H_
diff --git a/media/audio/win/wavein_input_win.cc b/media/audio/win/wavein_input_win.cc
deleted file mode 100644
index 18bf53f..0000000
--- a/media/audio/win/wavein_input_win.cc
+++ /dev/null
@@ -1,325 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/audio/win/wavein_input_win.h"
-
-#include "base/logging.h"
-#include "media/audio/audio_device_description.h"
-#include "media/audio/audio_io.h"
-#include "media/audio/win/audio_manager_win.h"
-#include "media/audio/win/device_enumeration_win.h"
-#include "media/base/audio_bus.h"
-
-namespace media {
-
-// Our sound buffers are allocated once and kept in a linked list using the
-// the WAVEHDR::dwUser variable. The last buffer points to the first buffer.
-static WAVEHDR* GetNextBuffer(WAVEHDR* current) {
-  return reinterpret_cast<WAVEHDR*>(current->dwUser);
-}
-
-PCMWaveInAudioInputStream::PCMWaveInAudioInputStream(
-    AudioManagerWin* manager,
-    const AudioParameters& params,
-    int num_buffers,
-    const std::string& device_id)
-    : state_(kStateEmpty),
-      manager_(manager),
-      callback_(NULL),
-      num_buffers_(num_buffers),
-      channels_(params.channels()),
-      device_id_(device_id),
-      wavein_(NULL),
-      buffer_(NULL),
-      audio_bus_(media::AudioBus::Create(params)) {
-  DCHECK_GT(num_buffers_, 0);
-  format_.wFormatTag = WAVE_FORMAT_PCM;
-  format_.nChannels = params.channels() > 2 ? 2 : params.channels();
-  format_.nSamplesPerSec = params.sample_rate();
-  format_.wBitsPerSample = params.bits_per_sample();
-  format_.cbSize = 0;
-  format_.nBlockAlign = (format_.nChannels * format_.wBitsPerSample) / 8;
-  format_.nAvgBytesPerSec = format_.nBlockAlign * format_.nSamplesPerSec;
-  buffer_size_ = params.frames_per_buffer() * format_.nBlockAlign;
-  // If we don't have a packet size we use 100ms.
-  if (!buffer_size_)
-    buffer_size_ = format_.nAvgBytesPerSec / 10;
-  // The event is auto-reset.
-  stopped_event_.Set(::CreateEventW(NULL, FALSE, FALSE, NULL));
-}
-
-PCMWaveInAudioInputStream::~PCMWaveInAudioInputStream() {
-  DCHECK(NULL == wavein_);
-}
-
-bool PCMWaveInAudioInputStream::Open() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (state_ != kStateEmpty)
-    return false;
-  if (num_buffers_ < 2 || num_buffers_ > 10)
-    return false;
-
-  // Convert the stored device id string into an unsigned integer
-  // corresponding to the selected device.
-  UINT device_id = WAVE_MAPPER;
-  if (!GetDeviceId(&device_id)) {
-    return false;
-  }
-
-  // Open the specified input device for recording.
-  MMRESULT result = MMSYSERR_NOERROR;
-  result = ::waveInOpen(&wavein_, device_id, &format_,
-                        reinterpret_cast<DWORD_PTR>(WaveCallback),
-                        reinterpret_cast<DWORD_PTR>(this),
-                        CALLBACK_FUNCTION);
-  if (result != MMSYSERR_NOERROR)
-    return false;
-
-  SetupBuffers();
-  state_ = kStateReady;
-  return true;
-}
-
-void PCMWaveInAudioInputStream::SetupBuffers() {
-  WAVEHDR* last = NULL;
-  WAVEHDR* first = NULL;
-  for (int ix = 0; ix != num_buffers_; ++ix) {
-    uint32_t sz = sizeof(WAVEHDR) + buffer_size_;
-    buffer_ =  reinterpret_cast<WAVEHDR*>(new char[sz]);
-    buffer_->lpData = reinterpret_cast<char*>(buffer_) + sizeof(WAVEHDR);
-    buffer_->dwBufferLength = buffer_size_;
-    buffer_->dwBytesRecorded = 0;
-    buffer_->dwUser = reinterpret_cast<DWORD_PTR>(last);
-    buffer_->dwFlags = WHDR_DONE;
-    buffer_->dwLoops = 0;
-    if (ix == 0)
-      first = buffer_;
-    last = buffer_;
-    ::waveInPrepareHeader(wavein_, buffer_, sizeof(WAVEHDR));
-  }
-  // Fix the first buffer to point to the last one.
-  first->dwUser = reinterpret_cast<DWORD_PTR>(last);
-}
-
-void PCMWaveInAudioInputStream::FreeBuffers() {
-  WAVEHDR* current = buffer_;
-  for (int ix = 0; ix != num_buffers_; ++ix) {
-    WAVEHDR* next = GetNextBuffer(current);
-    if (current->dwFlags & WHDR_PREPARED)
-      ::waveInUnprepareHeader(wavein_, current, sizeof(WAVEHDR));
-    delete[] reinterpret_cast<char*>(current);
-    current = next;
-  }
-  buffer_ = NULL;
-}
-
-void PCMWaveInAudioInputStream::Start(AudioInputCallback* callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (state_ != kStateReady)
-    return;
-
-  DCHECK(!callback_);
-  callback_ = callback;
-  state_ = kStateRecording;
-
-  WAVEHDR* buffer = buffer_;
-  for (int ix = 0; ix != num_buffers_; ++ix) {
-    QueueNextPacket(buffer);
-    buffer = GetNextBuffer(buffer);
-  }
-  buffer = buffer_;
-
-  MMRESULT result = ::waveInStart(wavein_);
-  if (result != MMSYSERR_NOERROR) {
-    HandleError(result);
-    state_ = kStateReady;
-    callback_ = NULL;
-  }
-}
-
-// Stopping is tricky. First, no buffer should be locked by the audio driver
-// or else the waveInReset() will deadlock and secondly, the callback should
-// not be inside the AudioInputCallback's OnData because waveInReset()
-// forcefully kills the callback thread.
-void PCMWaveInAudioInputStream::Stop() {
-  DVLOG(1) << "PCMWaveInAudioInputStream::Stop()";
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (state_ != kStateRecording)
-    return;
-
-  bool already_stopped = false;
-  {
-    // Tell the callback that we're stopping.
-    // As a result, |stopped_event_| will be signaled in callback method.
-    base::AutoLock auto_lock(lock_);
-    already_stopped = (callback_ == NULL);
-    callback_ = NULL;
-  }
-
-  if (already_stopped)
-    return;
-
-  // Wait for the callback to finish, it will signal us when ready to be reset.
-  DWORD wait = ::WaitForSingleObject(stopped_event_.Get(), INFINITE);
-  DCHECK_EQ(wait, WAIT_OBJECT_0);
-
-  // Stop input and reset the current position to zero for |wavein_|.
-  // All pending buffers are marked as done and returned to the application.
-  MMRESULT res = ::waveInReset(wavein_);
-  DCHECK_EQ(res, static_cast<MMRESULT>(MMSYSERR_NOERROR));
-
-  state_ = kStateReady;
-}
-
-void PCMWaveInAudioInputStream::Close() {
-  DVLOG(1) << "PCMWaveInAudioInputStream::Close()";
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  // We should not call Close() while recording. Catch it with DCHECK and
-  // implement auto-stop just in case.
-  DCHECK_NE(state_, kStateRecording);
-  Stop();
-
-  if (wavein_) {
-    FreeBuffers();
-
-    // waveInClose() generates a WIM_CLOSE callback.  In case Start() was never
-    // called, force a reset to ensure close succeeds.
-    MMRESULT res = ::waveInReset(wavein_);
-    DCHECK_EQ(res, static_cast<MMRESULT>(MMSYSERR_NOERROR));
-    res = ::waveInClose(wavein_);
-    DCHECK_EQ(res, static_cast<MMRESULT>(MMSYSERR_NOERROR));
-    state_ = kStateClosed;
-    wavein_ = NULL;
-  }
-
-  // Tell the audio manager that we have been released. This can result in
-  // the manager destroying us in-place so this needs to be the last thing
-  // we do on this function.
-  manager_->ReleaseInputStream(this);
-}
-
-double PCMWaveInAudioInputStream::GetMaxVolume() {
-  // TODO(henrika): Add volume support using the Audio Mixer API.
-  return 0.0;
-}
-
-void PCMWaveInAudioInputStream::SetVolume(double volume) {
-  // TODO(henrika): Add volume support using the Audio Mixer API.
-}
-
-double PCMWaveInAudioInputStream::GetVolume() {
-  // TODO(henrika): Add volume support using the Audio Mixer API.
-  return 0.0;
-}
-
-bool PCMWaveInAudioInputStream::SetAutomaticGainControl(bool enabled) {
-  // TODO(henrika): Add AGC support when volume control has been added.
-  NOTIMPLEMENTED();
-  return false;
-}
-
-bool PCMWaveInAudioInputStream::GetAutomaticGainControl() {
-  // TODO(henrika): Add AGC support when volume control has been added.
-  NOTIMPLEMENTED();
-  return false;
-}
-
-bool PCMWaveInAudioInputStream::IsMuted() {
-  NOTIMPLEMENTED();
-  return false;
-}
-
-void PCMWaveInAudioInputStream::HandleError(MMRESULT error) {
-  DLOG(WARNING) << "PCMWaveInAudio error " << error;
-  if (callback_)
-    callback_->OnError(this);
-}
-
-void PCMWaveInAudioInputStream::QueueNextPacket(WAVEHDR *buffer) {
-  MMRESULT res = ::waveInAddBuffer(wavein_, buffer, sizeof(WAVEHDR));
-  if (res != MMSYSERR_NOERROR)
-    HandleError(res);
-}
-
-bool PCMWaveInAudioInputStream::GetDeviceId(UINT* device_index) {
-  // Deliver the default input device id (WAVE_MAPPER) if the default
-  // device has been selected.
-  if (device_id_ == AudioDeviceDescription::kDefaultDeviceId) {
-    *device_index = WAVE_MAPPER;
-    return true;
-  }
-
-  // Get list of all available and active devices.
-  AudioDeviceNames device_names;
-  if (!media::GetInputDeviceNamesWinXP(&device_names))
-    return false;
-
-  if (device_names.empty())
-    return false;
-
-  // Search the full list of devices and compare with the specified
-  // device id which was specified in the constructor. Stop comparing
-  // when a match is found and return the corresponding index.
-  UINT index = 0;
-  bool found_device = false;
-  AudioDeviceNames::const_iterator it = device_names.begin();
-  while (it != device_names.end()) {
-    if (it->unique_id.compare(device_id_) == 0) {
-      *device_index = index;
-      found_device = true;
-      break;
-    }
-    ++index;
-    ++it;
-  }
-
-  return found_device;
-}
-
-// Windows calls us back in this function when some events happen. Most notably
-// when it has an audio buffer with recorded data.
-void PCMWaveInAudioInputStream::WaveCallback(HWAVEIN hwi, UINT msg,
-                                             DWORD_PTR instance,
-                                             DWORD_PTR param1, DWORD_PTR) {
-  PCMWaveInAudioInputStream* obj =
-      reinterpret_cast<PCMWaveInAudioInputStream*>(instance);
-
-  // The lock ensures that Stop() can't be called during a callback.
-  base::AutoLock auto_lock(obj->lock_);
-
-  if (msg == WIM_DATA) {
-    // The WIM_DATA message is sent when waveform-audio data is present in
-    // the input buffer and the buffer is being returned to the application.
-    // The message can be sent when the buffer is full or after the
-    // waveInReset function is called.
-    if (obj->callback_) {
-      // TODO(henrika): the |volume| parameter is always set to zero since
-      // there is currently no support for controlling the microphone volume
-      // level.
-      WAVEHDR* buffer = reinterpret_cast<WAVEHDR*>(param1);
-      obj->audio_bus_->FromInterleaved(
-          reinterpret_cast<uint8_t*>(buffer->lpData), obj->audio_bus_->frames(),
-          obj->format_.wBitsPerSample / 8);
-      obj->callback_->OnData(
-          obj, obj->audio_bus_.get(), buffer->dwBytesRecorded, 0.0);
-
-      // Queue the finished buffer back with the audio driver. Since we are
-      // reusing the same buffers we can get away without calling
-      // waveInPrepareHeader.
-      obj->QueueNextPacket(buffer);
-    } else {
-      // Main thread has called Stop() and set |callback_| to NULL and is
-      // now waiting to issue waveInReset which will kill this thread.
-      // We should not call AudioSourceCallback code anymore.
-      ::SetEvent(obj->stopped_event_.Get());
-    }
-  } else if (msg == WIM_CLOSE) {
-    // Intentionaly no-op for now.
-  } else if (msg == WIM_OPEN) {
-    // Intentionaly no-op for now.
-  }
-}
-
-}  // namespace media
diff --git a/media/audio/win/wavein_input_win.h b/media/audio/win/wavein_input_win.h
deleted file mode 100644
index 17af10f..0000000
--- a/media/audio/win/wavein_input_win.h
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_AUDIO_WIN_WAVEIN_INPUT_WIN_H_
-#define MEDIA_AUDIO_WIN_WAVEIN_INPUT_WIN_H_
-
-#include <windows.h>
-#include <mmsystem.h>
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/synchronization/lock.h"
-#include "base/threading/thread_checker.h"
-#include "base/win/scoped_handle.h"
-#include "media/audio/audio_io.h"
-#include "media/base/audio_parameters.h"
-
-namespace media {
-
-class AudioBus;
-class AudioManagerWin;
-
-class PCMWaveInAudioInputStream : public AudioInputStream {
- public:
-  // The ctor takes all the usual parameters, plus |manager| which is the
-  // the audio manager who is creating this object and |device_id| which
-  // is provided by the operating system.
-  PCMWaveInAudioInputStream(AudioManagerWin* manager,
-                            const AudioParameters& params,
-                            int num_buffers,
-                            const std::string& device_id);
-  ~PCMWaveInAudioInputStream() override;
-
-  // Implementation of AudioInputStream.
-  bool Open() override;
-  void Start(AudioInputCallback* callback) override;
-  void Stop() override;
-  void Close() override;
-  // TODO(henrika): Add volume support using the Audio Mixer API.
-  double GetMaxVolume() override;
-  void SetVolume(double volume) override;
-  double GetVolume() override;
-  bool SetAutomaticGainControl(bool enabled) override;
-  bool GetAutomaticGainControl() override;
-  bool IsMuted() override;
-
- private:
-  enum State {
-    kStateEmpty,      // Initial state.
-    kStateReady,      // Device obtained and ready to record.
-    kStateRecording,  // Recording audio.
-    kStateStopping,   // Trying to stop, waiting for callback to finish.
-    kStateStopped,    // Stopped. Device was reset.
-    kStateClosed      // Device has been released.
-  };
-
-  // Allow unit tests to query the device ID.
-  friend class AudioManagerTest;
-
-  // Windows calls us back with the recorded audio data here. See msdn
-  // documentation for 'waveInProc' for details about the parameters.
-  static void CALLBACK WaveCallback(HWAVEIN hwi, UINT msg, DWORD_PTR instance,
-                                    DWORD_PTR param1, DWORD_PTR param2);
-
-  // If windows reports an error this function handles it and passes it to
-  // the attached AudioInputCallback::OnError().
-  void HandleError(MMRESULT error);
-
-  // Allocates and prepares the memory that will be used for recording.
-  void SetupBuffers();
-
-  // Deallocates the memory allocated in SetupBuffers.
-  void FreeBuffers();
-
-  // Sends a buffer to the audio driver for recording.
-  void QueueNextPacket(WAVEHDR* buffer);
-
-  // Converts the stored device id string into an unsigned integer which
-  // can be used by waveInOpen() to open the specified capture device.
-  bool GetDeviceId(UINT* device_index);
-
-  base::ThreadChecker thread_checker_;
-
-  // Reader beware. Visual C has stronger guarantees on volatile vars than
-  // most people expect. In fact, it has release semantics on write and
-  // acquire semantics on reads. See the msdn documentation.
-  volatile State state_;
-
-  // The audio manager that created this input stream. We notify it when
-  // we close so it can release its own resources.
-  AudioManagerWin* manager_;
-
-  // We use the callback mostly to periodically give the recorded audio data.
-  AudioInputCallback* callback_;
-
-  // The number of buffers of size |buffer_size_| each to use.
-  const int num_buffers_;
-
-  // The size in bytes of each audio buffer.
-  uint32_t buffer_size_;
-
-  // Channels, 1 or 2.
-  const int channels_;
-
-  // Contains the unique name of the selected endpoint device.
-  // Note that AudioDeviceDescription::kDefaultDeviceId represents the default
-  // device role and is not a valid ID as such.
-  std::string device_id_;
-
-  // Windows native structure to encode the format parameters.
-  WAVEFORMATEX format_;
-
-  // Handle to the instance of the wave device.
-  HWAVEIN wavein_;
-
-  // Pointer to the first allocated audio buffer. This object owns it.
-  WAVEHDR* buffer_;
-
-  // An event that is signaled when the callback thread is ready to stop.
-  base::win::ScopedHandle stopped_event_;
-
-  // Lock used to avoid conflicts when Stop() is called during a callback.
-  base::Lock lock_;
-
-  // Extra audio bus used for storage of deinterleaved data for the OnData
-  // callback.
-  std::unique_ptr<media::AudioBus> audio_bus_;
-
-  DISALLOW_COPY_AND_ASSIGN(PCMWaveInAudioInputStream);
-};
-
-}  // namespace media
-
-#endif  // MEDIA_AUDIO_WIN_WAVEIN_INPUT_WIN_H_
diff --git a/media/mojo/common/mojo_decoder_buffer_converter.cc b/media/mojo/common/mojo_decoder_buffer_converter.cc
index 0a12aa60..32080d3 100644
--- a/media/mojo/common/mojo_decoder_buffer_converter.cc
+++ b/media/mojo/common/mojo_decoder_buffer_converter.cc
@@ -63,7 +63,9 @@
 
 MojoDecoderBufferReader::MojoDecoderBufferReader(
     mojo::ScopedDataPipeConsumerHandle consumer_handle)
-    : consumer_handle_(std::move(consumer_handle)), bytes_read_(0) {
+    : consumer_handle_(std::move(consumer_handle)),
+      pipe_watcher_(FROM_HERE),
+      bytes_read_(0) {
   DVLOG(1) << __func__;
 
   MojoResult result =
@@ -183,7 +185,9 @@
 
 MojoDecoderBufferWriter::MojoDecoderBufferWriter(
     mojo::ScopedDataPipeProducerHandle producer_handle)
-    : producer_handle_(std::move(producer_handle)), bytes_written_(0) {
+    : producer_handle_(std::move(producer_handle)),
+      pipe_watcher_(FROM_HERE),
+      bytes_written_(0) {
   DVLOG(1) << __func__;
 
   MojoResult result =
diff --git a/media/remoting/demuxer_stream_adapter.cc b/media/remoting/demuxer_stream_adapter.cc
index 54dd7b27..c12ee00 100644
--- a/media/remoting/demuxer_stream_adapter.cc
+++ b/media/remoting/demuxer_stream_adapter.cc
@@ -57,6 +57,7 @@
       pending_flush_(false),
       current_pending_frame_offset_(0),
       pending_frame_is_eos_(false),
+      write_watcher_(FROM_HERE),
       media_status_(DemuxerStream::kOk),
       producer_handle_(std::move(producer_handle)),
       bytes_written_to_pipe_(0),
diff --git a/mojo/android/system/watcher_impl.cc b/mojo/android/system/watcher_impl.cc
index b9dc206..2a6c54cf 100644
--- a/mojo/android/system/watcher_impl.cc
+++ b/mojo/android/system/watcher_impl.cc
@@ -28,7 +28,7 @@
 class WatcherWithMessageLoopObserver
     : public base::MessageLoop::DestructionObserver {
  public:
-  WatcherWithMessageLoopObserver() {}
+  WatcherWithMessageLoopObserver() : watcher_(FROM_HERE) {}
 
   ~WatcherWithMessageLoopObserver() override { StopObservingIfNecessary(); }
 
diff --git a/mojo/common/data_pipe_drainer.cc b/mojo/common/data_pipe_drainer.cc
index 1133e11..27bd893d 100644
--- a/mojo/common/data_pipe_drainer.cc
+++ b/mojo/common/data_pipe_drainer.cc
@@ -15,7 +15,10 @@
 
 DataPipeDrainer::DataPipeDrainer(Client* client,
                                  mojo::ScopedDataPipeConsumerHandle source)
-    : client_(client), source_(std::move(source)), weak_factory_(this) {
+    : client_(client),
+      source_(std::move(source)),
+      handle_watcher_(FROM_HERE),
+      weak_factory_(this) {
   DCHECK(client_);
   handle_watcher_.Start(
       source_.get(), MOJO_HANDLE_SIGNAL_READABLE,
diff --git a/mojo/edk/js/drain_data.cc b/mojo/edk/js/drain_data.cc
index 6bb4a46..cfd0bb5 100644
--- a/mojo/edk/js/drain_data.cc
+++ b/mojo/edk/js/drain_data.cc
@@ -21,7 +21,9 @@
 namespace js {
 
 DrainData::DrainData(v8::Isolate* isolate, mojo::Handle handle)
-    : isolate_(isolate), handle_(DataPipeConsumerHandle(handle.value())) {
+    : isolate_(isolate),
+      handle_(DataPipeConsumerHandle(handle.value())),
+      handle_watcher_(FROM_HERE) {
   v8::Handle<v8::Context> context(isolate_->GetCurrentContext());
   runner_ = gin::PerContextData::From(context)->runner()->GetWeakPtr();
 
diff --git a/mojo/edk/js/waiting_callback.cc b/mojo/edk/js/waiting_callback.cc
index 4ba2c61..fada039 100644
--- a/mojo/edk/js/waiting_callback.cc
+++ b/mojo/edk/js/waiting_callback.cc
@@ -53,6 +53,7 @@
                                  v8::Handle<v8::Function> callback,
                                  bool one_shot)
     : one_shot_(one_shot),
+      watcher_(FROM_HERE),
       weak_factory_(this) {
   v8::Handle<v8::Context> context = isolate->GetCurrentContext();
   runner_ = gin::PerContextData::From(context)->runner()->GetWeakPtr();
diff --git a/mojo/edk/system/data_pipe_unittest.cc b/mojo/edk/system/data_pipe_unittest.cc
index 32e661e..f444621 100644
--- a/mojo/edk/system/data_pipe_unittest.cc
+++ b/mojo/edk/system/data_pipe_unittest.cc
@@ -1932,7 +1932,7 @@
             loop->Quit();
         },
         &run_loop, &count);
-    Watcher producer_watcher, consumer_watcher;
+    Watcher producer_watcher(FROM_HERE), consumer_watcher(FROM_HERE);
     producer_watcher.Start(
         Handle(producers[1]), MOJO_HANDLE_SIGNAL_PEER_CLOSED, callback);
     consumer_watcher.Start(
diff --git a/mojo/edk/system/multiprocess_message_pipe_unittest.cc b/mojo/edk/system/multiprocess_message_pipe_unittest.cc
index 2ba0c388..498980c 100644
--- a/mojo/edk/system/multiprocess_message_pipe_unittest.cc
+++ b/mojo/edk/system/multiprocess_message_pipe_unittest.cc
@@ -1274,7 +1274,7 @@
   // Wait on handle 1 using a Watcher.
   {
     base::RunLoop run_loop;
-    Watcher watcher;
+    Watcher watcher(FROM_HERE);
     watcher.Start(Handle(handles[1]), MOJO_HANDLE_SIGNAL_PEER_CLOSED,
                   base::Bind([] (base::RunLoop* loop, MojoResult result) {
                     EXPECT_EQ(MOJO_RESULT_OK, result);
diff --git a/mojo/public/cpp/bindings/connector.h b/mojo/public/cpp/bindings/connector.h
index dcfe8cb..1ccc795 100644
--- a/mojo/public/cpp/bindings/connector.h
+++ b/mojo/public/cpp/bindings/connector.h
@@ -150,6 +150,10 @@
     return task_runner_.get();
   }
 
+  // Sets the tag used by the heap profiler.
+  // |tag| must be a const string literal.
+  void SetWatcherHeapProfilerTag(const char* tag);
+
  private:
   // Callback of mojo::Watcher.
   void OnWatcherHandleReady(MojoResult result);
@@ -206,6 +210,10 @@
   base::Lock connected_lock_;
   bool connected_ = true;
 
+  // The tag used to track heap allocations that originated from a Watcher
+  // notification.
+  const char* heap_profiler_tag_ = nullptr;
+
   // Create a single weak ptr and use it everywhere, to avoid the malloc/free
   // cost of creating a new weak ptr whenever it is needed.
   // NOTE: This weak pointer is invalidated when the message pipe is closed or
diff --git a/mojo/public/cpp/bindings/lib/connector.cc b/mojo/public/cpp/bindings/lib/connector.cc
index 6452411..433e45e 100644
--- a/mojo/public/cpp/bindings/lib/connector.cc
+++ b/mojo/public/cpp/bindings/lib/connector.cc
@@ -179,6 +179,13 @@
   return sync_watcher_->SyncWatch(should_stop);
 }
 
+void Connector::SetWatcherHeapProfilerTag(const char* tag) {
+  heap_profiler_tag_ = tag;
+  if (handle_watcher_) {
+    handle_watcher_->set_heap_profiler_tag(tag);
+  }
+}
+
 void Connector::OnWatcherHandleReady(MojoResult result) {
   OnHandleReadyInternal(result);
 }
@@ -210,7 +217,8 @@
   CHECK(!paused_);
   DCHECK(!handle_watcher_);
 
-  handle_watcher_.reset(new Watcher(task_runner_));
+  handle_watcher_.reset(new Watcher(FROM_HERE, task_runner_));
+  handle_watcher_->set_heap_profiler_tag(heap_profiler_tag_);
   MojoResult rv = handle_watcher_->Start(
       message_pipe_.get(), MOJO_HANDLE_SIGNAL_READABLE,
       base::Bind(&Connector::OnWatcherHandleReady, base::Unretained(this)));
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.cc b/mojo/public/cpp/bindings/lib/multiplex_router.cc
index 1681b7fa..17f2258 100644
--- a/mojo/public/cpp/bindings/lib/multiplex_router.cc
+++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc
@@ -361,11 +361,13 @@
   DCHECK(endpoints_.empty());
 }
 
-void MultiplexRouter::SetMasterInterfaceName(const std::string& name) {
+void MultiplexRouter::SetMasterInterfaceName(const char* name) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  header_validator_->SetDescription(name + " [master] MessageHeaderValidator");
+  header_validator_->SetDescription(
+      std::string(name) + " [master] MessageHeaderValidator");
   control_message_handler_.SetDescription(
-      name + " [master] PipeControlMessageHandler");
+      std::string(name) + " [master] PipeControlMessageHandler");
+  connector_.SetWatcherHeapProfilerTag(name);
 }
 
 void MultiplexRouter::CreateEndpointHandlePair(
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.h b/mojo/public/cpp/bindings/lib/multiplex_router.h
index f874a4b..c1e0298 100644
--- a/mojo/public/cpp/bindings/lib/multiplex_router.h
+++ b/mojo/public/cpp/bindings/lib/multiplex_router.h
@@ -79,7 +79,8 @@
 
   // Sets the master interface name for this router. Only used when reporting
   // message header or control message validation errors.
-  void SetMasterInterfaceName(const std::string& name);
+  // |name| must be a string literal.
+  void SetMasterInterfaceName(const char* name);
 
   // ---------------------------------------------------------------------------
   // The following public methods are safe to call from any threads.
diff --git a/mojo/public/cpp/system/tests/watcher_unittest.cc b/mojo/public/cpp/system/tests/watcher_unittest.cc
index ebeebf6..9b59240 100644
--- a/mojo/public/cpp/system/tests/watcher_unittest.cc
+++ b/mojo/public/cpp/system/tests/watcher_unittest.cc
@@ -48,7 +48,7 @@
 
   bool notified = false;
   base::RunLoop run_loop;
-  Watcher b_watcher;
+  Watcher b_watcher(FROM_HERE);
   EXPECT_EQ(MOJO_RESULT_OK,
             b_watcher.Start(b.get(), MOJO_HANDLE_SIGNAL_READABLE,
                             OnReady([&] (MojoResult result) {
@@ -71,7 +71,7 @@
   CreateMessagePipe(nullptr, &a, &b);
   a.reset();
 
-  Watcher b_watcher;
+  Watcher b_watcher(FROM_HERE);
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
             b_watcher.Start(b.get(), MOJO_HANDLE_SIGNAL_READABLE,
                             NotReached()));
@@ -84,7 +84,7 @@
   a.reset();
   b.reset();
 
-  Watcher b_watcher;
+  Watcher b_watcher(FROM_HERE);
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
             b_watcher.Start(b.get(), MOJO_HANDLE_SIGNAL_READABLE,
                             NotReached()));
@@ -96,7 +96,7 @@
   CreateMessagePipe(nullptr, &a, &b);
 
   base::RunLoop run_loop;
-  Watcher b_watcher;
+  Watcher b_watcher(FROM_HERE);
   EXPECT_EQ(MOJO_RESULT_OK,
             b_watcher.Start(b.get(), MOJO_HANDLE_SIGNAL_READABLE,
                             NotReached()));
@@ -118,7 +118,7 @@
   CreateMessagePipe(nullptr, &a, &b);
 
   base::RunLoop run_loop;
-  Watcher b_watcher;
+  Watcher b_watcher(FROM_HERE);
   EXPECT_EQ(MOJO_RESULT_OK,
             b_watcher.Start(b.get(), MOJO_HANDLE_SIGNAL_READABLE,
                             OnReady([&] (MojoResult result) {
@@ -140,7 +140,7 @@
   CreateMessagePipe(nullptr, &a, &b);
   base::RunLoop run_loop;
   {
-    Watcher b_watcher;
+    Watcher b_watcher(FROM_HERE);
     EXPECT_EQ(MOJO_RESULT_OK,
               b_watcher.Start(b.get(), MOJO_HANDLE_SIGNAL_READABLE,
                               NotReached()));
@@ -161,7 +161,7 @@
   ScopedMessagePipeHandle a, b;
   CreateMessagePipe(nullptr, &a, &b);
 
-  Watcher b_watcher;
+  Watcher b_watcher(FROM_HERE);
   EXPECT_EQ(MOJO_RESULT_OK,
             b_watcher.Start(b.get(), MOJO_HANDLE_SIGNAL_READABLE,
                             OnReady([](MojoResult result) { FAIL(); })));
diff --git a/mojo/public/cpp/system/watcher.cc b/mojo/public/cpp/system/watcher.cc
index fc03c5a0..55dcf40 100644
--- a/mojo/public/cpp/system/watcher.cc
+++ b/mojo/public/cpp/system/watcher.cc
@@ -7,14 +7,17 @@
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/macros.h"
+#include "base/trace_event/heap_profiler.h"
 #include "mojo/public/c/system/functions.h"
 
 namespace mojo {
 
-Watcher::Watcher(scoped_refptr<base::SingleThreadTaskRunner> runner)
+Watcher::Watcher(const tracked_objects::Location& from_here,
+                 scoped_refptr<base::SingleThreadTaskRunner> runner)
     : task_runner_(std::move(runner)),
       is_default_task_runner_(task_runner_ ==
                               base::ThreadTaskRunnerHandle::Get()),
+      heap_profiler_tag_(from_here.file_name()),
       weak_factory_(this) {
   DCHECK(task_runner_->BelongsToCurrentThread());
   weak_self_ = weak_factory_.GetWeakPtr();
@@ -79,8 +82,10 @@
   }
 
   // NOTE: It's legal for |callback| to delete |this|.
-  if (!callback.is_null())
+  if (!callback.is_null()) {
+    TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION event(heap_profiler_tag_);
     callback.Run(result);
+  }
 }
 
 // static
@@ -94,6 +99,7 @@
   // TODO: Maybe we should also expose |signals_state| through the Watcher API.
   // Current HandleWatcher users have no need for it, so it's omitted here.
   Watcher* watcher = reinterpret_cast<Watcher*>(context);
+
   if ((flags & MOJO_WATCH_NOTIFICATION_FLAG_FROM_SYSTEM) &&
       watcher->task_runner_->RunsTasksOnCurrentThread() &&
       watcher->is_default_task_runner_) {
diff --git a/mojo/public/cpp/system/watcher.h b/mojo/public/cpp/system/watcher.h
index 815b73b..236788b 100644
--- a/mojo/public/cpp/system/watcher.h
+++ b/mojo/public/cpp/system/watcher.h
@@ -36,8 +36,9 @@
   //       been cancelled implicitly.
   using ReadyCallback = base::Callback<void(MojoResult result)>;
 
-  explicit Watcher(scoped_refptr<base::SingleThreadTaskRunner> runner =
-                       base::ThreadTaskRunnerHandle::Get());
+  Watcher(const tracked_objects::Location& from_here,
+          scoped_refptr<base::SingleThreadTaskRunner> runner =
+              base::ThreadTaskRunnerHandle::Get());
 
   // NOTE: This destructor automatically calls |Cancel()| if the Watcher is
   // still active.
@@ -74,6 +75,12 @@
   Handle handle() const { return handle_; }
   ReadyCallback ready_callback() const { return callback_; }
 
+ // Sets the tag used by the heap profiler.
+ // |tag| must be a const string literal.
+ void set_heap_profiler_tag(const char* heap_profiler_tag) {
+   heap_profiler_tag_ = heap_profiler_tag;
+ }
+
  private:
   void OnHandleReady(MojoResult result);
 
@@ -104,6 +111,10 @@
   // The callback to call when the handle is signaled.
   ReadyCallback callback_;
 
+  // Tag used to ID memory allocations that originated from notifications in
+  // this watcher.
+  const char* heap_profiler_tag_ = nullptr;
+
   base::WeakPtrFactory<Watcher> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(Watcher);
diff --git a/net/quic/core/congestion_control/bbr_sender.cc b/net/quic/core/congestion_control/bbr_sender.cc
index c04427e..7dd17cb1 100644
--- a/net/quic/core/congestion_control/bbr_sender.cc
+++ b/net/quic/core/congestion_control/bbr_sender.cc
@@ -7,7 +7,6 @@
 #include <algorithm>
 #include <sstream>
 
-#include "base/stl_util.h"
 #include "net/quic/core/congestion_control/rtt_stats.h"
 #include "net/quic/core/quic_flags.h"
 #include "net/quic/platform/api/quic_bug_tracker.h"
diff --git a/net/quic/core/crypto/quic_crypto_server_config.cc b/net/quic/core/crypto/quic_crypto_server_config.cc
index 655c145..4e6f0310 100644
--- a/net/quic/core/crypto/quic_crypto_server_config.cc
+++ b/net/quic/core/crypto/quic_crypto_server_config.cc
@@ -42,7 +42,6 @@
 #include "net/quic/platform/api/quic_url_utils.h"
 
 using base::StringPiece;
-using crypto::SecureHash;
 using std::string;
 
 namespace net {
@@ -67,6 +66,8 @@
 
 }  // namespace
 
+using crypto::SecureHash;
+
 class ValidateClientHelloHelper {
  public:
   // Note: stores a pointer to a unique_ptr, and std::moves the unique_ptr when
diff --git a/net/quic/core/quic_client_session_base.cc b/net/quic/core/quic_client_session_base.cc
index a353372..12f9ff7 100644
--- a/net/quic/core/quic_client_session_base.cc
+++ b/net/quic/core/quic_client_session_base.cc
@@ -79,47 +79,50 @@
 }
 
 bool QuicClientSessionBase::HandlePromised(QuicStreamId /* associated_id */,
-                                           QuicStreamId id,
+                                           QuicStreamId promised_id,
                                            const SpdyHeaderBlock& headers) {
   // Due to pathalogical packet re-ordering, it is possible that
   // frames for the promised stream have already arrived, and the
   // promised stream could be active or closed.
-  if (IsClosedStream(id)) {
+  if (IsClosedStream(promised_id)) {
     // There was a RST on the data stream already, perhaps
     // QUIC_REFUSED_STREAM?
-    QUIC_DVLOG(1) << "Promise ignored for stream " << id
+    QUIC_DVLOG(1) << "Promise ignored for stream " << promised_id
                   << " that is already closed";
     return false;
   }
 
   if (push_promise_index_->promised_by_url()->size() >= get_max_promises()) {
-    QUIC_DVLOG(1) << "Too many promises, rejecting promise for stream " << id;
-    ResetPromised(id, QUIC_REFUSED_STREAM);
+    QUIC_DVLOG(1) << "Too many promises, rejecting promise for stream "
+                  << promised_id;
+    ResetPromised(promised_id, QUIC_REFUSED_STREAM);
     return false;
   }
 
   const string url = SpdyUtils::GetUrlFromHeaderBlock(headers);
   QuicClientPromisedInfo* old_promised = GetPromisedByUrl(url);
   if (old_promised) {
-    QUIC_DVLOG(1) << "Promise for stream " << id << " is duplicate URL " << url
+    QUIC_DVLOG(1) << "Promise for stream " << promised_id
+                  << " is duplicate URL " << url
                   << " of previous promise for stream " << old_promised->id();
-    ResetPromised(id, QUIC_DUPLICATE_PROMISE_URL);
+    ResetPromised(promised_id, QUIC_DUPLICATE_PROMISE_URL);
     return false;
   }
 
-  if (GetPromisedById(id)) {
+  if (GetPromisedById(promised_id)) {
     // OnPromiseHeadersComplete() would have closed the connection if
     // promised id is a duplicate.
-    QUIC_BUG << "Duplicate promise for id " << id;
+    QUIC_BUG << "Duplicate promise for id " << promised_id;
     return false;
   }
 
-  QuicClientPromisedInfo* promised = new QuicClientPromisedInfo(this, id, url);
+  QuicClientPromisedInfo* promised =
+      new QuicClientPromisedInfo(this, promised_id, url);
   std::unique_ptr<QuicClientPromisedInfo> promised_owner(promised);
   promised->Init();
-  QUIC_DVLOG(1) << "stream " << id << " emplace url " << url;
+  QUIC_DVLOG(1) << "stream " << promised_id << " emplace url " << url;
   (*push_promise_index_->promised_by_url())[url] = promised;
-  promised_by_id_[id] = std::move(promised_owner);
+  promised_by_id_[promised_id] = std::move(promised_owner);
   promised->OnPromiseHeaders(headers);
   return true;
 }
diff --git a/net/quic/core/quic_connection.cc b/net/quic/core/quic_connection.cc
index bbca1e3..1b5e2bf 100644
--- a/net/quic/core/quic_connection.cc
+++ b/net/quic/core/quic_connection.cc
@@ -17,8 +17,6 @@
 #include "base/format_macros.h"
 #include "base/macros.h"
 #include "base/metrics/histogram_macros.h"
-#include "net/base/address_family.h"
-#include "net/base/ip_address.h"
 #include "net/base/net_errors.h"
 #include "net/quic/core/crypto/crypto_protocol.h"
 #include "net/quic/core/crypto/quic_decrypter.h"
diff --git a/net/quic/core/quic_flags_list.h b/net/quic/core/quic_flags_list.h
index 86f5196..f39651b 100644
--- a/net/quic/core/quic_flags_list.h
+++ b/net/quic/core/quic_flags_list.h
@@ -31,9 +31,6 @@
           FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support,
           true)
 
-// This flag is not in use, just to keep consistency for shared code.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_always_log_bugs_for_tests, true)
-
 // If true, multipath is enabled for the connection.
 QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_multipath, false)
 
diff --git a/net/quic/core/quic_framer.cc b/net/quic/core/quic_framer.cc
index df632bb3..1ae1e3e 100644
--- a/net/quic/core/quic_framer.cc
+++ b/net/quic/core/quic_framer.cc
@@ -28,7 +28,6 @@
 
 using base::StringPiece;
 using std::string;
-#define PREDICT_FALSE(x) (x)
 
 namespace net {
 
@@ -1999,7 +1998,7 @@
         ++num_ack_blocks_written;
       }
       if (num_ack_blocks_written >= num_ack_blocks) {
-        if (PREDICT_FALSE(num_ack_blocks_written != num_ack_blocks)) {
+        if (QUIC_PREDICT_FALSE(num_ack_blocks_written != num_ack_blocks)) {
           QUIC_BUG << "Wrote " << num_ack_blocks_written
                    << ", expected to write " << num_ack_blocks;
         }
diff --git a/net/quic/core/quic_one_block_arena.h b/net/quic/core/quic_one_block_arena.h
index 022918b4..a3f13fa8 100644
--- a/net/quic/core/quic_one_block_arena.h
+++ b/net/quic/core/quic_one_block_arena.h
@@ -15,8 +15,7 @@
 #include "net/quic/core/quic_arena_scoped_ptr.h"
 #include "net/quic/core/quic_types.h"
 #include "net/quic/platform/api/quic_bug_tracker.h"
-
-#define PREDICT_FALSE(x) x
+#include "net/quic/platform/api/quic_logging.h"
 
 namespace net {
 
@@ -60,7 +59,7 @@
       << "Object is too large for the arena.";
   static_assert(QUIC_ALIGN_OF(T) > 1,
                 "Objects added to the arena must be at least 2B aligned.");
-  if (PREDICT_FALSE(offset_ > ArenaSize - AlignedSize<T>())) {
+  if (QUIC_PREDICT_FALSE(offset_ > ArenaSize - AlignedSize<T>())) {
     QUIC_BUG << "Ran out of space in QuicOneBlockArena at " << this
              << ", max size was " << ArenaSize << ", failing request was "
              << AlignedSize<T>() << ", end of arena was " << offset_;
diff --git a/net/quic/core/quic_sent_packet_manager.cc b/net/quic/core/quic_sent_packet_manager.cc
index 7758c5c..852fa09 100644
--- a/net/quic/core/quic_sent_packet_manager.cc
+++ b/net/quic/core/quic_sent_packet_manager.cc
@@ -280,7 +280,7 @@
          pending_retransmissions_.front().second == LOSS_RETRANSMISSION) {
     // Cancel any pending retransmissions larger than largest_newly_acked_.
     unacked_packets_.RestoreToInFlight(pending_retransmissions_.front().first);
-    pending_retransmissions_.erase(pending_retransmissions_.begin());
+    pending_retransmissions_.pop_front();
   }
 
   if (debug_delegate_ != nullptr) {
@@ -438,7 +438,7 @@
 
 QuicPendingRetransmission QuicSentPacketManager::NextPendingRetransmission() {
   QUIC_BUG_IF(pending_retransmissions_.empty())
-      << "Unexpected call to PendingRetransmissions() with empty pending "
+      << "Unexpected call to NextPendingRetransmission() with empty pending "
       << "retransmission list. Corrupted memory usage imminent.";
   QuicPacketNumber packet_number = pending_retransmissions_.begin()->first;
   TransmissionType transmission_type = pending_retransmissions_.begin()->second;
diff --git a/net/quic/core/quic_spdy_stream.cc b/net/quic/core/quic_spdy_stream.cc
index b004fcd7..2f39ea4 100644
--- a/net/quic/core/quic_spdy_stream.cc
+++ b/net/quic/core/quic_spdy_stream.cc
@@ -6,7 +6,6 @@
 
 #include <utility>
 
-#include "net/base/parse_number.h"
 #include "net/quic/core/quic_spdy_session.h"
 #include "net/quic/core/quic_utils.h"
 #include "net/quic/core/quic_write_blocked_list.h"
@@ -293,7 +292,6 @@
   if (status.size() != 3) {
     return false;
   }
-
   // First character must be an integer in range [1,5].
   if (status[0] < '1' || status[0] > '5') {
     return false;
diff --git a/net/quic/core/quic_stream_sequencer_test.cc b/net/quic/core/quic_stream_sequencer_test.cc
index 0e04007..7111d8e 100644
--- a/net/quic/core/quic_stream_sequencer_test.cc
+++ b/net/quic/core/quic_stream_sequencer_test.cc
@@ -401,7 +401,7 @@
 
   QuicSequencerRandomTest() {
     uint64_t seed = QuicRandom::GetInstance()->RandUint64();
-    VLOG(1) << "**** The current seed is " << seed << " ****";
+    QUIC_LOG(INFO) << "**** The current seed is " << seed << " ****";
     random_.set_seed(seed);
 
     CreateFrames();
diff --git a/net/quic/core/quic_unacked_packet_map.cc b/net/quic/core/quic_unacked_packet_map.cc
index d545639..62a687c7 100644
--- a/net/quic/core/quic_unacked_packet_map.cc
+++ b/net/quic/core/quic_unacked_packet_map.cc
@@ -4,7 +4,6 @@
 
 #include "net/quic/core/quic_unacked_packet_map.h"
 
-#include "base/stl_util.h"
 #include "net/quic/core/quic_connection_stats.h"
 #include "net/quic/core/quic_utils.h"
 #include "net/quic/platform/api/quic_bug_tracker.h"
diff --git a/net/quic/core/quic_versions.cc b/net/quic/core/quic_versions.cc
index 4d18c96..8705df3 100644
--- a/net/quic/core/quic_versions.cc
+++ b/net/quic/core/quic_versions.cc
@@ -4,7 +4,6 @@
 
 #include "net/quic/core/quic_versions.h"
 
-#include "base/memory/ptr_util.h"
 #include "base/strings/string_piece.h"
 #include "net/quic/core/quic_error_codes.h"
 #include "net/quic/core/quic_flags.h"
diff --git a/net/quic/core/spdy_utils.cc b/net/quic/core/spdy_utils.cc
index ff3484f..a38d1765 100644
--- a/net/quic/core/spdy_utils.cc
+++ b/net/quic/core/spdy_utils.cc
@@ -120,7 +120,7 @@
     // TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec.
   }
 
-  QUIC_DVLOG(1) << "Successfully parsed Trailers.";
+  QUIC_DVLOG(1) << "Successfully parsed Trailers: " << trailers->DebugString();
   return true;
 }
 
diff --git a/net/quic/platform/api/quic_logging.h b/net/quic/platform/api/quic_logging.h
index 5f84020..3bc5f48 100644
--- a/net/quic/platform/api/quic_logging.h
+++ b/net/quic/platform/api/quic_logging.h
@@ -14,10 +14,13 @@
 
 #define QUIC_DVLOG(verbose_level) QUIC_DVLOG_IMPL(verbose_level)
 #define QUIC_DLOG(severity) QUIC_DLOG_IMPL(severity)
+#define QUIC_DLOG_IF(severity, condition) QUIC_DLOG_IF_IMPL(severity, condition)
 #define QUIC_LOG(severity) QUIC_LOG_IMPL(severity)
 #define QUIC_LOG_FIRST_N(severity, n) QUIC_LOG_FIRST_N_IMPL(severity, n)
 #define QUIC_LOG_EVERY_N_SEC(severity, seconds) \
   QUIC_LOG_EVERY_N_SEC_IMPL(severity, seconds)
 #define QUIC_LOG_IF(severity, condition) QUIC_LOG_IF_IMPL(severity, condition)
 
+#define QUIC_PREDICT_FALSE(x) QUIC_PREDICT_FALSE_IMPL(x)
+
 #endif  // NET_QUIC_PLATFORM_API_QUIC_LOGGING_H_
diff --git a/net/quic/platform/impl/quic_logging_impl.h b/net/quic/platform/impl/quic_logging_impl.h
index 000b20b..6daa47f 100644
--- a/net/quic/platform/impl/quic_logging_impl.h
+++ b/net/quic/platform/impl/quic_logging_impl.h
@@ -11,6 +11,8 @@
 #define QUIC_LOG_EVERY_N_SEC_IMPL(severity, seconds) QUIC_LOG_IMPL(severity)
 #define QUIC_LOG_FIRST_N_IMPL(severity, n) QUIC_LOG_IMPL(severity)
 #define QUIC_DLOG_IMPL(severity) QUIC_CHROMIUM_DLOG_##severity
+#define QUIC_DLOG_IF_IMPL(severity, condition) \
+  QUIC_CHROMIUM_DLOG_IF_##severity(condition)
 #define QUIC_LOG_IF_IMPL(severity, condition) \
   QUIC_CHROMIUM_LOG_IF_##severity(condition)
 
@@ -32,6 +34,12 @@
 #define QUIC_CHROMIUM_LOG_IF_FATAL(condition) LOG_IF(FATAL, condition)
 #define QUIC_CHROMIUM_LOG_IF_DFATAL(condition) LOG_IF(DFATAL, condition)
 
+#define QUIC_CHROMIUM_DLOG_IF_INFO(condition) DVLOG_IF(1, condition)
+#define QUIC_CHROMIUM_DLOG_IF_WARNING(condition) DLOG_IF(WARNING, condition)
+#define QUIC_CHROMIUM_DLOG_IF_ERROR(condition) DLOG_IF(ERROR, condition)
+#define QUIC_CHROMIUM_DLOG_IF_FATAL(condition) DLOG_IF(FATAL, condition)
+#define QUIC_CHROMIUM_DLOG_IF_DFATAL(condition) DLOG_IF(DFATAL, condition)
+
 #define QUIC_DVLOG_IMPL(verbose_level) DVLOG(verbose_level)
 
 #if defined(OS_WIN)
@@ -42,6 +50,9 @@
 #define QUIC_CHROMIUM_LOG_0 QUIC_CHROMIUM_LOG_ERROR
 #define QUIC_CHROMIUM_DLOG_0 QUIC_CHROMIUM_DLOG_ERROR
 #define QUIC_CHROMIUM_LOG_IF_0 QUIC_CHROMIUM_LOG_IF_ERROR
+#define QUIC_CHROMIUM_DLOG_IF_0 QUIC_CHROMIUM_DLOG_IF_ERROR
 #endif
 
+#define QUIC_PREDICT_FALSE_IMPL(x) x
+
 #endif  // NET_QUIC_PLATFORM_IMPL_QUIC_LOGGING_IMPL_H_
diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc
index e5ea47d..fd24d8b 100644
--- a/net/tools/quic/quic_dispatcher.cc
+++ b/net/tools/quic/quic_dispatcher.cc
@@ -501,7 +501,7 @@
     return;
   }
 
-  DVLOG_IF(1, error != QUIC_NO_ERROR)
+  QUIC_DLOG_IF(INFO, error != QUIC_NO_ERROR)
       << "Closing connection (" << connection_id
       << ") due to error: " << QuicErrorCodeToString(error)
       << ", with details: " << error_details;
diff --git a/services/catalog/public/tools/catalog.cc.tmpl b/services/catalog/public/tools/catalog.cc.tmpl
new file mode 100644
index 0000000..d309ae99
--- /dev/null
+++ b/services/catalog/public/tools/catalog.cc.tmpl
@@ -0,0 +1,58 @@
+// Copyright 2017 The Chromium 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 is a generated file. Please see the "catalog_cpp_source" template in
+// src/services/catalog/public/tools/catalog.gni for more details.
+
+#include "{{path}}.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/values.h"
+
+namespace {
+
+template <typename T>
+std::unique_ptr<base::Value> GenerateValue(T generator) { return generator(); }
+
+}  // namespace
+
+{%- macro generate_value(source) -%}
+{%-   if source|is_dict -%}
+GenerateValue([]() {
+  auto dict = base::MakeUnique<base::DictionaryValue>();
+{%-     for key, value in source.iteritems() %}
+  dict->Set("{{key}}", {{generate_value(value)|indent(2)}});
+{%-     endfor %}
+  return dict;
+})
+{%-   elif source|is_list -%}
+GenerateValue([]() {
+  auto list = base::MakeUnique<base::ListValue>();
+{%-     for value in source %}
+  list->Append({{generate_value(value)|indent(2)}});
+{%-     endfor %}
+  return list;
+})
+{%-   elif source|is_number -%}
+base::MakeUnique<base::FundamentalValue>({{source}})
+{%-   elif source|is_bool -%}
+base::MakeUnique<base::FundamentalValue>({{source|lower}})
+{%-   elif source|is_string or source|is_unicode -%}
+base::MakeUnique<base::StringValue>("{{source|make_ascii}}")
+{%-   else %}
+{{raise("Unknown value type: %s" % source, source)}}
+{%-   endif %}
+{%- endmacro -%}
+
+{% for namespace in namespaces %}
+namespace {{namespace}} {
+{%- endfor %}
+
+std::unique_ptr<base::Value> {{function_name}}() {
+  return {{generate_value(catalog)|indent(2)}};
+}
+
+{%- for namespace in namespaces|reverse %}
+}  // namespace {{namespace}}
+{%- endfor %}
diff --git a/services/catalog/public/tools/catalog.gni b/services/catalog/public/tools/catalog.gni
index 67a5774..4aeaa2a 100644
--- a/services/catalog/public/tools/catalog.gni
+++ b/services/catalog/public/tools/catalog.gni
@@ -147,13 +147,14 @@
 #   catalog
 #       The catalog target whose output should be stringified.
 #
-#   output_symbol_name
+#   generated_function_name
 #       The fully qualified symbol name of the C++ string constant to define in
 #       the generate source_set.
 #
 template("catalog_cpp_source") {
   assert(defined(invoker.catalog), "catalog is required")
-  assert(defined(invoker.output_symbol_name), "output_symbol_name is required")
+  assert(defined(invoker.generated_function_name),
+         "generated_function_name is required")
 
   catalog_target = invoker.catalog
   catalog_target_dir = get_label_info(catalog_target, "target_gen_dir")
@@ -161,21 +162,27 @@
   catalog_filename = "$catalog_target_dir/${catalog_target_name}.json"
 
   generator_target_name = "${target_name}__generator"
-  generated_filename = "${target_gen_dir}/${target_name}.cc"
+  generated_filename_base = "${target_gen_dir}/${target_name}"
 
   action(generator_target_name) {
     testonly = defined(invoker.testonly) && invoker.testonly
     script = "//services/catalog/public/tools/sourcify_manifest.py"
     inputs = [
       catalog_filename,
+
+      "//services/catalog/public/tools/catalog.cc.tmpl",
+      "//services/catalog/public/tools/catalog.h.tmpl",
     ]
     outputs = [
-      generated_filename,
+      "${generated_filename_base}.cc",
+      "${generated_filename_base}.h",
     ]
     args = [
       "--input=" + rebase_path(catalog_filename, root_build_dir),
-      "--output=" + rebase_path(generated_filename, root_build_dir),
-      "--symbol-name=" + invoker.output_symbol_name,
+      "--output-filename-base=" +
+          rebase_path(generated_filename_base, root_build_dir),
+      "--output-function-name=" + invoker.generated_function_name,
+      "--module-path=" + rebase_path(generated_filename_base, root_gen_dir),
     ]
     if (is_debug || dcheck_always_on) {
       args += [ "--pretty" ]
@@ -190,6 +197,7 @@
     sources = get_target_outputs(":$generator_target_name")
     deps = [
       ":$generator_target_name",
+      "//base",
     ]
   }
 }
diff --git a/services/catalog/public/tools/catalog.h.tmpl b/services/catalog/public/tools/catalog.h.tmpl
new file mode 100644
index 0000000..5018974
--- /dev/null
+++ b/services/catalog/public/tools/catalog.h.tmpl
@@ -0,0 +1,29 @@
+// Copyright 2017 The Chromium 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 is a generated file. Please see the "catalog_cpp_source" template in
+// src/services/catalog/public/tools/catalog.gni for more details.
+{%- set header_guard = "%s_H_"|format(path)|upper|replace("/", "_")|
+        replace(".", "_")|replace("-", "_") %}
+
+#ifndef {{header_guard}}
+#define {{header_guard}}
+
+#include <memory>
+
+namespace base {
+class Value;
+}
+
+{% for namespace in namespaces %}
+namespace {{namespace}} {
+{%- endfor %}
+
+std::unique_ptr<base::Value> {{function_name}}();
+
+{% for namespace in namespaces|reverse %}
+}  // namespace {{namespace}}
+{%- endfor %}
+
+#endif  // {{header_guard}}
diff --git a/services/catalog/public/tools/sourcify_manifest.py b/services/catalog/public/tools/sourcify_manifest.py
index 81c219d..6744b7f 100755
--- a/services/catalog/public/tools/sourcify_manifest.py
+++ b/services/catalog/public/tools/sourcify_manifest.py
@@ -3,56 +3,109 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-"""Generates a C++ source file which defines a string constant containing the
-contents of a catalog manifest file. Useful for baking catalogs into binaries
-which don't want to hit disk before initializing the catalog."""
+"""Generates C++ source and header files defining function to create an
+in-memory representation of a static catalog manifest at runtime."""
+
 
 import argparse
+import imp
 import json
 import os.path
 import sys
 
 
-# Token used to delimit raw strings in the generated source file. It's illegal
-# for this token to appear within the contents of the input manifest itself.
-_RAW_STRING_DELIMITER = "#CATALOG_JSON#"
+_H_FILE_TEMPLATE = "catalog.h.tmpl"
+_CC_FILE_TEMPLATE = "catalog.cc.tmpl"
+
+
+# Disable lint check for finding modules:
+# pylint: disable=F0401
+
+def _GetDirAbove(dirname):
+  """Returns the directory "above" this file containing |dirname| (which must
+  also be "above" this file)."""
+  path = os.path.abspath(__file__)
+  while True:
+    path, tail = os.path.split(path)
+    assert tail
+    if tail == dirname:
+      return path
+
+
+try:
+  imp.find_module("jinja2")
+except ImportError:
+  sys.path.append(os.path.join(_GetDirAbove("services"), "third_party"))
+import jinja2
+
+
+def ApplyTemplate(path_to_template, output_path, global_vars, **kwargs):
+  def make_ascii(maybe_unicode):
+    if type(maybe_unicode) is str:
+      return maybe_unicode
+    assert type(maybe_unicode) is unicode
+    return maybe_unicode.encode("ascii", "ignore")
+
+  with open(output_path, "w") as output_file:
+    jinja_env = jinja2.Environment(
+        loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
+        keep_trailing_newline=True, **kwargs)
+    jinja_env.globals.update(global_vars)
+    jinja_env.filters.update({
+      "is_dict": lambda x : type(x) is dict,
+      "is_list": lambda x : type(x) is list,
+      "is_number": lambda x : type(x) is int or type(x) is float,
+      "is_bool": lambda x: type(x) is bool,
+      "is_string": lambda x: type(x) is str,
+      "is_unicode": lambda x: type(x) is unicode,
+      "make_ascii": make_ascii,
+    })
+    output_file.write(jinja_env.get_template(path_to_template).render())
 
 
 def main():
   parser = argparse.ArgumentParser(
       description="Generates a C++ constant containing a catalog manifest.")
   parser.add_argument("--input")
-  parser.add_argument("--output")
-  parser.add_argument("--symbol-name")
-  parser.add_argument("--pretty", action="store_true")
+  parser.add_argument("--output-filename-base")
+  parser.add_argument("--output-function-name")
+  parser.add_argument("--module-path")
   args, _ = parser.parse_known_args()
 
-  if args.input is None or args.output is None or args.symbol_name is None:
-    raise Exception("--input, --output, and --symbol-name are required")
+  if args.input is None:
+    raise Exception("--input is required")
+  if args.output_filename_base is None:
+    raise Exception("--output-filename-base is required")
+  if args.output_function_name is None:
+    raise Exception("--output-function-name is required")
+  if args.module_path is None:
+    raise Exception("--module-path is required")
 
-  with open(args.input, 'r') as input_file:
-    manifest_contents = input_file.read()
+  with open(args.input, "r") as input_file:
+    catalog = json.load(input_file)
 
-  if manifest_contents.find(_RAW_STRING_DELIMITER) >= 0:
-    raise Exception(
-        "Unexpected '%s' found in input manifest." % _RAW_STRING_DELIMITER)
+  qualified_function_name = args.output_function_name.split("::")
+  namespaces = qualified_function_name[0:-1]
+  function_name = qualified_function_name[-1]
 
-  qualified_symbol_name = args.symbol_name.split("::")
-  namespace = qualified_symbol_name[0:-1]
-  symbol_name = qualified_symbol_name[-1]
+  def raise_error(error, value):
+    raise Exception(error)
 
-  with open(args.output, 'w') as output_file:
-    output_file.write(
-        "// This is a generated file produced by\n"
-        "// src/services/catalog/public/tools/sourcify_manifest.py.\n\n")
-    for name in namespace:
-      output_file.write("namespace %s {\n" % name)
-    output_file.write("\nextern const char %s[];" % symbol_name)
-    output_file.write("\nconst char %s[] = R\"%s(%s)%s\";\n\n" %
-        (symbol_name, _RAW_STRING_DELIMITER, manifest_contents,
-            _RAW_STRING_DELIMITER))
-    for name in reversed(namespace):
-      output_file.write("}  // %s\n" % name)
+  global_vars = {
+    "catalog": catalog,
+    "function_name": function_name,
+    "namespaces": namespaces,
+    "path": args.module_path,
+    "raise": raise_error,
+  }
+
+  input_h_filename = _H_FILE_TEMPLATE
+  output_h_filename = "%s.h" % args.output_filename_base
+  ApplyTemplate(input_h_filename, output_h_filename, global_vars)
+
+  input_cc_filename = _CC_FILE_TEMPLATE
+  output_cc_filename = "%s.cc" % args.output_filename_base
+  ApplyTemplate(input_cc_filename, output_cc_filename, global_vars)
 
   return 0
 
diff --git a/services/service_manager/public/cpp/test/run_all_service_tests_with_catalog.cc b/services/service_manager/public/cpp/test/run_all_service_tests_with_catalog.cc
index bce6a6c..8d02f3f 100644
--- a/services/service_manager/public/cpp/test/run_all_service_tests_with_catalog.cc
+++ b/services/service_manager/public/cpp/test/run_all_service_tests_with_catalog.cc
@@ -2,14 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <memory>
-
-#include "base/json/json_reader.h"
 #include "base/message_loop/message_loop.h"
 #include "base/test/launcher/unit_test_launcher.h"
 #include "base/test/test_suite.h"
 #include "base/threading/thread.h"
-#include "base/values.h"
 #include "mojo/edk/embedder/embedder.h"
 #include "mojo/edk/embedder/scoped_ipc_support.h"
 #include "services/catalog/catalog.h"
@@ -18,10 +14,8 @@
 int main(int argc, char** argv) {
   base::TestSuite test_suite(argc, argv);
 
-  std::unique_ptr<base::Value> manifest_value =
-      base::JSONReader::Read(service_manager::test::kServiceTestCatalog);
-  DCHECK(manifest_value);
-  catalog::Catalog::SetDefaultCatalogManifest(std::move(manifest_value));
+  catalog::Catalog::SetDefaultCatalogManifest(
+      service_manager::test::CreateTestCatalog());
 
   mojo::edk::Init();
 
diff --git a/services/service_manager/public/cpp/test/service_test_catalog.h b/services/service_manager/public/cpp/test/service_test_catalog.h
index 2a627c2..fa98ea0 100644
--- a/services/service_manager/public/cpp/test/service_test_catalog.h
+++ b/services/service_manager/public/cpp/test/service_test_catalog.h
@@ -2,17 +2,28 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifndef SERVICES_SERVICE_MANAGER_PUBLIC_CPP_TEST_SERVICE_TEST_CATALOG_H_
+#define SERVICES_SERVICE_MANAGER_PUBLIC_CPP_TEST_SERVICE_TEST_CATALOG_H_
+
+#include <memory>
+
+namespace base {
+class Value;
+}
+
 namespace service_manager {
 namespace test {
 
-// This symbol must be defined by any target linking against the
+// This function must be defined by any target linking against the
 // ":run_all_service_tests" target in this directory. Use the service_test
 // GN template defined in
 // src/services/service_manager/public/tools/test/service_test.gni to
-// autogenerate and link against a definition of the symbol dervied from the
-// contents of a generated service catalog. See the service_test.gni
-// documentation for more details.
-extern const char kServiceTestCatalog[];
+// autogenerate and link against a definition of the function generated from the
+// contents of a catalog manifest. See the service_test.gni documentation for
+// more details.
+std::unique_ptr<base::Value> CreateTestCatalog();
 
 }  // namespace test
 }  // namespace service_manager
+
+#endif  // SERVICES_SERVICE_MANAGER_PUBLIC_CPP_TEST_SERVICE_TEST_CATALOG_H_
diff --git a/services/service_manager/public/tools/test/service_test.gni b/services/service_manager/public/tools/test/service_test.gni
index 9f5508c..ad7e358 100644
--- a/services/service_manager/public/tools/test/service_test.gni
+++ b/services/service_manager/public/tools/test/service_test.gni
@@ -32,6 +32,6 @@
 
   catalog_cpp_source(catalog_source_target) {
     catalog = invoker.catalog
-    output_symbol_name = "service_manager::test::kServiceTestCatalog"
+    generated_function_name = "service_manager::test::CreateTestCatalog"
   }
 }
diff --git a/services/ui/demo/mus_demo.cc b/services/ui/demo/mus_demo.cc
index b268e11c..0ae145c 100644
--- a/services/ui/demo/mus_demo.cc
+++ b/services/ui/demo/mus_demo.cc
@@ -138,6 +138,8 @@
   return true;
 }
 
+void MusDemo::OnWmSetCanFocus(aura::Window* window, bool can_focus) {}
+
 aura::Window* MusDemo::OnWmCreateTopLevelWindow(
     mojom::WindowType window_type,
     std::map<std::string, std::vector<uint8_t>>* properties) {
diff --git a/services/ui/demo/mus_demo.h b/services/ui/demo/mus_demo.h
index c471c18..f78e948 100644
--- a/services/ui/demo/mus_demo.h
+++ b/services/ui/demo/mus_demo.h
@@ -74,6 +74,7 @@
       aura::Window* window,
       const std::string& name,
       std::unique_ptr<std::vector<uint8_t>>* new_data) override;
+  void OnWmSetCanFocus(aura::Window* window, bool can_focus) override;
   aura::Window* OnWmCreateTopLevelWindow(
       ui::mojom::WindowType window_type,
       std::map<std::string, std::vector<uint8_t>>* properties) override;
diff --git a/services/ui/public/interfaces/window_manager.mojom b/services/ui/public/interfaces/window_manager.mojom
index 14ad1c0..f73d91b 100644
--- a/services/ui/public/interfaces/window_manager.mojom
+++ b/services/ui/public/interfaces/window_manager.mojom
@@ -35,6 +35,9 @@
 
   // Properties used only during creation time. --------------------------------
 
+  // Whether the window should be initially focusable or not. Type: bool.
+  const string kFocusable_InitProperty = "init:focusable";
+
   // Initial bounds to create the window at. If empty the WindowManager decides
   // the initial bounds. Type: gfx::Rect.
   const string kBounds_InitProperty = "init:bounds";
@@ -169,6 +172,8 @@
                 string name,
                 array<uint8>? value);
 
+  WmSetCanFocus(uint32 window_id, bool can_focus);
+
   // Asks the WindowManager to create a new window.
   // |requesting_client_id| is the id of the client issuing the request. This
   // allows the window manager to track top level windows by client.
@@ -196,6 +201,9 @@
   // to the next. The window manager may completely ignore this message.
   WmDeactivateWindow(uint32 window_id);
 
+  // Asks the WindowMangaer to stack |above_id| in front of |below_id|.
+  WmStackAbove(uint32 change_id, uint32 above_id, uint32 below_id);
+
   // Asks the WindowManager to stack |window_id| as the first child of its
   // window manager owned parent.
   WmStackAtTop(uint32 change_id, uint32 window_id);
diff --git a/services/ui/public/interfaces/window_tree.mojom b/services/ui/public/interfaces/window_tree.mojom
index 51c1726..d2343db 100644
--- a/services/ui/public/interfaces/window_tree.mojom
+++ b/services/ui/public/interfaces/window_tree.mojom
@@ -264,6 +264,10 @@
   // window manager change the focus to the next activatable window.
   DeactivateWindow(uint32 window_id);
 
+  // Stacks the window |above_id| above |below_id|. These two windows must
+  // share the same parent.
+  StackAbove(uint32 change_id, uint32 above_id, uint32 below_id);
+
   // Stacks the window above all sibling windows.
   StackAtTop(uint32 change_id, uint32 window_id);
 
diff --git a/services/ui/test_wm/test_wm.cc b/services/ui/test_wm/test_wm.cc
index f678e028..743db072 100644
--- a/services/ui/test_wm/test_wm.cc
+++ b/services/ui/test_wm/test_wm.cc
@@ -107,6 +107,7 @@
       std::unique_ptr<std::vector<uint8_t>>* new_data) override {
     return true;
   }
+  void OnWmSetCanFocus(aura::Window* window, bool can_focus) override {}
   aura::Window* OnWmCreateTopLevelWindow(
       ui::mojom::WindowType window_type,
       std::map<std::string, std::vector<uint8_t>>* properties) override {
diff --git a/services/ui/ws/access_policy.h b/services/ui/ws/access_policy.h
index 823a270..fa5b236 100644
--- a/services/ui/ws/access_policy.h
+++ b/services/ui/ws/access_policy.h
@@ -60,6 +60,8 @@
   virtual bool CanSetHitTestMask(const ServerWindow* window) const = 0;
   virtual bool CanSetAcceptDrops(const ServerWindow* window) const = 0;
   virtual bool CanSetAcceptEvents(const ServerWindow* window) const = 0;
+  virtual bool CanStackAbove(const ServerWindow* above,
+                             const ServerWindow* below) const = 0;
   virtual bool CanStackAtTop(const ServerWindow* window) const = 0;
   // Used for all client controllable cursor properties; which cursor should be
   // displayed, visibility, locking, etc.
diff --git a/services/ui/ws/default_access_policy.cc b/services/ui/ws/default_access_policy.cc
index 5b65ab8..689108d 100644
--- a/services/ui/ws/default_access_policy.cc
+++ b/services/ui/ws/default_access_policy.cc
@@ -156,6 +156,14 @@
          delegate_->HasRootForAccessPolicy(window);
 }
 
+bool DefaultAccessPolicy::CanStackAbove(const ServerWindow* above,
+                                        const ServerWindow* below) const {
+  return delegate_->HasRootForAccessPolicy(above) &&
+         delegate_->IsWindowCreatedByWindowManager(above) &&
+         delegate_->HasRootForAccessPolicy(below) &&
+         delegate_->IsWindowCreatedByWindowManager(below);
+}
+
 bool DefaultAccessPolicy::CanStackAtTop(const ServerWindow* window) const {
   return delegate_->HasRootForAccessPolicy(window) &&
          delegate_->IsWindowCreatedByWindowManager(window);
diff --git a/services/ui/ws/default_access_policy.h b/services/ui/ws/default_access_policy.h
index 7791c6e..92f13765f 100644
--- a/services/ui/ws/default_access_policy.h
+++ b/services/ui/ws/default_access_policy.h
@@ -53,6 +53,8 @@
   bool CanSetHitTestMask(const ServerWindow* window) const override;
   bool CanSetAcceptDrops(const ServerWindow* window) const override;
   bool CanSetAcceptEvents(const ServerWindow* window) const override;
+  bool CanStackAbove(const ServerWindow* above,
+                     const ServerWindow* below) const override;
   bool CanStackAtTop(const ServerWindow* window) const override;
   bool CanSetCursorProperties(const ServerWindow* window) const override;
   bool CanInitiateDragLoop(const ServerWindow* window) const override;
diff --git a/services/ui/ws/event_dispatcher.cc b/services/ui/ws/event_dispatcher.cc
index 18d3dafe..f954ac54 100644
--- a/services/ui/ws/event_dispatcher.cc
+++ b/services/ui/ws/event_dispatcher.cc
@@ -37,24 +37,6 @@
          button_only_flags == ui::EF_RIGHT_MOUSE_BUTTON;
 }
 
-bool IsLocationInNonclientArea(const ServerWindow* target,
-                               const gfx::Point& location) {
-  if (!target->parent())
-    return false;
-
-  gfx::Rect client_area(target->bounds().size());
-  client_area.Inset(target->client_area());
-  if (client_area.Contains(location))
-    return false;
-
-  for (const auto& rect : target->additional_client_areas()) {
-    if (rect.Contains(location))
-      return false;
-  }
-
-  return true;
-}
-
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -221,31 +203,29 @@
 
 void EventDispatcher::UpdateNonClientAreaForCurrentWindow() {
   if (mouse_cursor_source_window_) {
-    gfx::Point location = mouse_pointer_last_location_;
-    ServerWindow* target = FindDeepestVisibleWindowForEvents(&location);
-    if (target == mouse_cursor_source_window_) {
-      mouse_cursor_in_non_client_area_ =
-          mouse_cursor_source_window_
-              ? IsLocationInNonclientArea(mouse_cursor_source_window_, location)
-              : false;
+    DeepestWindow deepest_window =
+        FindDeepestVisibleWindowForEvents(mouse_pointer_last_location_);
+    if (deepest_window.window == mouse_cursor_source_window_) {
+      mouse_cursor_in_non_client_area_ = mouse_cursor_source_window_
+                                             ? deepest_window.in_non_client_area
+                                             : false;
     }
   }
 }
 
 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() {
   if (!mouse_button_down_) {
-    gfx::Point location = mouse_pointer_last_location_;
-    mouse_cursor_source_window_ = FindDeepestVisibleWindowForEvents(&location);
-    if (!mouse_cursor_source_window_) {
-      location = mouse_pointer_last_location_;
+    DeepestWindow deepest_window =
+        FindDeepestVisibleWindowForEvents(mouse_pointer_last_location_);
+    mouse_cursor_source_window_ = deepest_window.window;
+    if (mouse_cursor_source_window_) {
+      mouse_cursor_in_non_client_area_ = deepest_window.in_non_client_area;
+    } else {
+      gfx::Point location = mouse_pointer_last_location_;
       mouse_cursor_source_window_ =
           delegate_->GetRootWindowContaining(&location);
+      mouse_cursor_in_non_client_area_ = true;
     }
-
-    mouse_cursor_in_non_client_area_ =
-        mouse_cursor_source_window_
-            ? IsLocationInNonclientArea(mouse_cursor_source_window_, location)
-            : false;
   }
 }
 
@@ -467,14 +447,14 @@
 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent(
     const ui::LocatedEvent& event) {
   PointerTarget pointer_target;
-  gfx::Point location(event.root_location());
-  ServerWindow* target_window = FindDeepestVisibleWindowForEvents(&location);
+  DeepestWindow deepest_window =
+      FindDeepestVisibleWindowForEvents(event.root_location());
   pointer_target.window =
-      modal_window_controller_.GetTargetForWindow(target_window);
+      modal_window_controller_.GetTargetForWindow(deepest_window.window);
   pointer_target.is_mouse_event = event.IsMousePointerEvent();
   pointer_target.in_nonclient_area =
-      target_window != pointer_target.window || !pointer_target.window ||
-      IsLocationInNonclientArea(pointer_target.window, location);
+      deepest_window.window != pointer_target.window ||
+      !pointer_target.window || deepest_window.in_non_client_area;
   pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN;
   return pointer_target;
 }
@@ -566,13 +546,14 @@
   return nullptr;
 }
 
-ServerWindow* EventDispatcher::FindDeepestVisibleWindowForEvents(
-    gfx::Point* location) {
-  ServerWindow* root = delegate_->GetRootWindowContaining(location);
-  if (!root)
-    return nullptr;
-
-  return ui::ws::FindDeepestVisibleWindowForEvents(root, location);
+DeepestWindow EventDispatcher::FindDeepestVisibleWindowForEvents(
+    const gfx::Point& location) {
+  gfx::Point relative_location(location);
+  // For the case of no root.
+  ServerWindow* root = delegate_->GetRootWindowContaining(&relative_location);
+  return root ? ui::ws::FindDeepestVisibleWindowForEvents(root,
+                                                          relative_location)
+              : DeepestWindow();
 }
 
 void EventDispatcher::CancelImplicitCaptureExcept(ServerWindow* window,
diff --git a/services/ui/ws/event_dispatcher.h b/services/ui/ws/event_dispatcher.h
index 7d9cb63c..6e146ab 100644
--- a/services/ui/ws/event_dispatcher.h
+++ b/services/ui/ws/event_dispatcher.h
@@ -28,6 +28,7 @@
 namespace ws {
 
 class Accelerator;
+struct DeepestWindow;
 class DragController;
 class DragSource;
 class DragTargetConnection;
@@ -225,7 +226,7 @@
   Accelerator* FindAccelerator(const ui::KeyEvent& event,
                                const ui::mojom::AcceleratorPhase phase);
 
-  ServerWindow* FindDeepestVisibleWindowForEvents(gfx::Point* location);
+  DeepestWindow FindDeepestVisibleWindowForEvents(const gfx::Point& location);
 
   // Clears the implicit captures in |pointer_targets_|, with the exception of
   // |window|. |window| may be null. |client_id| is the target client of
diff --git a/services/ui/ws/test_utils.cc b/services/ui/ws/test_utils.cc
index 1506bdc..5d87a75 100644
--- a/services/ui/ws/test_utils.cc
+++ b/services/ui/ws/test_utils.cc
@@ -241,6 +241,10 @@
 
 void TestWindowManager::WmDeactivateWindow(uint32_t window_id) {}
 
+void TestWindowManager::WmStackAbove(uint32_t change_id,
+                                     uint32_t above_id,
+                                     uint32_t below_id) {}
+
 void TestWindowManager::WmStackAtTop(uint32_t change_id, uint32_t window_id) {}
 
 void TestWindowManager::OnAccelerator(uint32_t ack_id,
diff --git a/services/ui/ws/test_utils.h b/services/ui/ws/test_utils.h
index 43ce2a55..9469b95 100644
--- a/services/ui/ws/test_utils.h
+++ b/services/ui/ws/test_utils.h
@@ -341,6 +341,7 @@
       uint32_t window_id,
       const std::string& name,
       const base::Optional<std::vector<uint8_t>>& value) override {}
+  void WmSetCanFocus(uint32_t window_id, bool can_focus) override {}
   void WmCreateTopLevelWindow(
       uint32_t change_id,
       ClientSpecificId requesting_client_id,
@@ -354,6 +355,8 @@
                          const gfx::Point& cursor_location) override;
   void WmCancelMoveLoop(uint32_t window_id) override;
   void WmDeactivateWindow(uint32_t window_id) override;
+  void WmStackAbove(uint32_t change_id, uint32_t above_id,
+                    uint32_t below_id) override;
   void WmStackAtTop(uint32_t change_id, uint32_t window_id) override;
   void OnAccelerator(uint32_t ack_id,
                      uint32_t accelerator_id,
diff --git a/services/ui/ws/window_finder.cc b/services/ui/ws/window_finder.cc
index b9792c2a3..c687378d 100644
--- a/services/ui/ws/window_finder.cc
+++ b/services/ui/ws/window_finder.cc
@@ -15,6 +15,7 @@
 
 namespace ui {
 namespace ws {
+namespace {
 
 bool IsValidWindowForEvents(ServerWindow* window) {
   ServerWindowCompositorFrameSinkManager* compositor_frame_sink_manager =
@@ -26,20 +27,45 @@
          compositor_frame_sink_manager->HasCompositorFrameSink();
 }
 
-ServerWindow* FindDeepestVisibleWindowForEvents(ServerWindow* window,
-                                                gfx::Point* location) {
-  if (!window->can_accept_events())
-    return nullptr;
+bool IsLocationInNonclientArea(const ServerWindow* target,
+                               const gfx::Point& location) {
+  if (!target->parent())
+    return false;
+
+  gfx::Rect client_area(target->bounds().size());
+  client_area.Inset(target->client_area());
+  if (client_area.Contains(location))
+    return false;
+
+  for (const auto& rect : target->additional_client_areas()) {
+    if (rect.Contains(location))
+      return false;
+  }
+
+  return true;
+}
+
+bool FindDeepestVisibleWindowForEventsImpl(ServerWindow* window,
+                                           const gfx::Point& location,
+                                           DeepestWindow* deepest_window) {
+  if (!window->can_accept_events()) {
+    if (!IsLocationInNonclientArea(window, location) ||
+        !IsValidWindowForEvents(window)) {
+      return false;
+    }
+    deepest_window->window = window;
+    deepest_window->in_non_client_area = true;
+    return true;
+  }
 
   const ServerWindow::Windows& children = window->children();
-  const gfx::Point original_location = *location;
   for (ServerWindow* child : base::Reversed(children)) {
-    if (!child->visible() || !child->can_accept_events())
+    if (!child->visible())
       continue;
 
     // TODO(sky): support transform.
-    gfx::Point location_in_child(original_location.x() - child->bounds().x(),
-                                 original_location.y() - child->bounds().y());
+    gfx::Point location_in_child(location.x() - child->bounds().x(),
+                                 location.y() - child->bounds().y());
     gfx::Rect child_bounds(child->bounds().size());
     child_bounds.Inset(-child->extended_hit_test_region().left(),
                        -child->extended_hit_test_region().top(),
@@ -51,12 +77,28 @@
       continue;
     }
 
-    *location = location_in_child;
-    ServerWindow* result = FindDeepestVisibleWindowForEvents(child, location);
-    if (result)
-      return result;
+    if (FindDeepestVisibleWindowForEventsImpl(child, location_in_child,
+                                              deepest_window)) {
+      return true;
+    }
   }
-  return IsValidWindowForEvents(window) ? window : nullptr;
+
+  if (!IsValidWindowForEvents(window))
+    return false;
+
+  deepest_window->window = window;
+  deepest_window->in_non_client_area =
+      IsLocationInNonclientArea(window, location);
+  return true;
+}
+
+}  // namespace
+
+DeepestWindow FindDeepestVisibleWindowForEvents(ServerWindow* root_window,
+                                                const gfx::Point& location) {
+  DeepestWindow result;
+  FindDeepestVisibleWindowForEventsImpl(root_window, location, &result);
+  return result;
 }
 
 gfx::Transform GetTransformToWindow(ServerWindow* window) {
diff --git a/services/ui/ws/window_finder.h b/services/ui/ws/window_finder.h
index a1dbe00..8f203c4 100644
--- a/services/ui/ws/window_finder.h
+++ b/services/ui/ws/window_finder.h
@@ -15,13 +15,17 @@
 
 class ServerWindow;
 
-// Find the deepest visible child of |root| that should receive an event at
-// |location|. |location| is initially in the coordinate space of
-// |root_window|, on return it is converted to the coordinates of the return
-// value. Returns null if there is no valid event target window over |location|.
-ServerWindow* FindDeepestVisibleWindowForEvents(
-    ServerWindow* root_window,
-    gfx::Point* location);
+struct DeepestWindow {
+  ServerWindow* window = nullptr;
+  bool in_non_client_area = false;
+};
+
+// Finds the deepest visible child of |root| that should receive an event at
+// |location|. |location| is in the coordinate space of |root_window|. The
+// |window| field in the returned structure is set to the child window. If no
+// valid child window is found |window| is set to null.
+DeepestWindow FindDeepestVisibleWindowForEvents(ServerWindow* root_window,
+                                                const gfx::Point& location);
 
 // Retrieve the transform to the provided |window|'s coordinate space from the
 // root.
diff --git a/services/ui/ws/window_finder_unittest.cc b/services/ui/ws/window_finder_unittest.cc
index 3cff8377..71b6c94 100644
--- a/services/ui/ws/window_finder_unittest.cc
+++ b/services/ui/ws/window_finder_unittest.cc
@@ -33,23 +33,71 @@
   child2.SetVisible(true);
   child2.SetBounds(gfx::Rect(15, 15, 20, 20));
 
-  gfx::Point local_point(16, 16);
-  EXPECT_EQ(&child2, FindDeepestVisibleWindowForEvents(&root, &local_point));
-  EXPECT_EQ(gfx::Point(1, 1), local_point);
+  EXPECT_EQ(
+      &child2,
+      FindDeepestVisibleWindowForEvents(&root, gfx::Point(16, 16)).window);
 
-  local_point.SetPoint(13, 14);
-  EXPECT_EQ(&child1, FindDeepestVisibleWindowForEvents(&root, &local_point));
-  EXPECT_EQ(gfx::Point(3, 4), local_point);
+  EXPECT_EQ(
+      &child1,
+      FindDeepestVisibleWindowForEvents(&root, gfx::Point(13, 14)).window);
 
-  local_point.SetPoint(13, 14);
   child1.set_can_accept_events(false);
-  EXPECT_EQ(nullptr, FindDeepestVisibleWindowForEvents(&root, &local_point));
-  EXPECT_EQ(gfx::Point(13, 14), local_point);
+  EXPECT_EQ(
+      nullptr,
+      FindDeepestVisibleWindowForEvents(&root, gfx::Point(13, 14)).window);
 
   child2.set_extended_hit_test_region(gfx::Insets(10, 10, 10, 10));
-  local_point.SetPoint(13, 14);
-  EXPECT_EQ(&child2, FindDeepestVisibleWindowForEvents(&root, &local_point));
-  EXPECT_EQ(gfx::Point(-2, -1), local_point);
+  EXPECT_EQ(
+      &child2,
+      FindDeepestVisibleWindowForEvents(&root, gfx::Point(13, 14)).window);
+}
+
+TEST(WindowFinderTest, FindDeepestVisibleWindowNonClientArea) {
+  TestServerWindowDelegate window_delegate;
+  ServerWindow root(&window_delegate, WindowId(1, 2));
+  EnableHitTest(&root);
+  window_delegate.set_root_window(&root);
+  root.SetVisible(true);
+  root.SetBounds(gfx::Rect(0, 0, 100, 100));
+
+  ServerWindow child1(&window_delegate, WindowId(1, 3));
+  root.Add(&child1);
+  EnableHitTest(&child1);
+  child1.SetVisible(true);
+  child1.SetBounds(gfx::Rect(10, 10, 20, 20));
+
+  DeepestWindow result =
+      FindDeepestVisibleWindowForEvents(&root, gfx::Point(13, 14));
+  EXPECT_EQ(&child1, result.window);
+  EXPECT_FALSE(result.in_non_client_area);
+
+  result = FindDeepestVisibleWindowForEvents(&root, gfx::Point(11, 11));
+  EXPECT_EQ(&child1, result.window);
+  EXPECT_FALSE(result.in_non_client_area);
+
+  // 11, 11 is over the non-client area.
+  child1.SetClientArea(gfx::Insets(2, 3, 4, 5), std::vector<gfx::Rect>());
+  result = FindDeepestVisibleWindowForEvents(&root, gfx::Point(11, 11));
+  EXPECT_EQ(&child1, result.window);
+  EXPECT_TRUE(result.in_non_client_area);
+
+  // 15, 15 is over the client area.
+  result = FindDeepestVisibleWindowForEvents(&root, gfx::Point(15, 15));
+  EXPECT_EQ(&child1, result.window);
+  EXPECT_FALSE(result.in_non_client_area);
+
+  // set_can_accept_events(false) should not impact the result for the
+  // non-client area.
+  child1.set_can_accept_events(false);
+  result = FindDeepestVisibleWindowForEvents(&root, gfx::Point(11, 11));
+  child1.SetClientArea(gfx::Insets(2, 3, 4, 5), std::vector<gfx::Rect>());
+  EXPECT_EQ(&child1, result.window);
+  EXPECT_TRUE(result.in_non_client_area);
+
+  // set_can_accept_events(false) means the client area won't be matched though.
+  result = FindDeepestVisibleWindowForEvents(&root, gfx::Point(15, 15));
+  EXPECT_EQ(&root, result.window);
+  EXPECT_FALSE(result.in_non_client_area);
 }
 
 TEST(WindowFinderTest, FindDeepestVisibleWindowHitTestMask) {
@@ -68,19 +116,17 @@
   child_with_mask.SetHitTestMask(gfx::Rect(2, 2, 16, 16));
 
   // Test a point inside the window but outside the mask.
-  gfx::Point point_outside_mask(11, 11);
-  EXPECT_EQ(&root,
-            FindDeepestVisibleWindowForEvents(&root, &point_outside_mask));
-  EXPECT_EQ(gfx::Point(11, 11), point_outside_mask);
+  EXPECT_EQ(
+      &root,
+      FindDeepestVisibleWindowForEvents(&root, gfx::Point(11, 11)).window);
 
   // Test a point inside the window and inside the mask.
-  gfx::Point point_inside_mask(15, 15);
-  EXPECT_EQ(&child_with_mask,
-            FindDeepestVisibleWindowForEvents(&root, &point_inside_mask));
-  EXPECT_EQ(gfx::Point(5, 5), point_inside_mask);
+  EXPECT_EQ(
+      &child_with_mask,
+      FindDeepestVisibleWindowForEvents(&root, gfx::Point(15, 15)).window);
 }
 
-TEST(WindowFinderTest, FindDeepestVisibleWindowForEventsOverNonTarget) {
+TEST(WindowFinderTest, FindDeepestVisibleWindowOverNonTarget) {
   TestServerWindowDelegate window_delegate;
   ServerWindow root(&window_delegate, WindowId(1, 2));
   window_delegate.set_root_window(&root);
@@ -100,11 +146,11 @@
   child2.SetVisible(true);
   child2.SetBounds(gfx::Rect(15, 15, 20, 20));
 
-  // |location_point| is over |child2| and |child1|, but as |child2| isn't a
-  // valid event taret |child2| should be picked.
-  gfx::Point local_point(16, 16);
-  EXPECT_EQ(&child1, FindDeepestVisibleWindowForEvents(&root, &local_point));
-  EXPECT_EQ(gfx::Point(6, 6), local_point);
+  // 16, 16 is over |child2| and |child1|, but as |child2| isn't a valid event
+  // target |child1| should be picked.
+  EXPECT_EQ(
+      &child1,
+      FindDeepestVisibleWindowForEvents(&root, gfx::Point(16, 16)).window);
 }
 
 }  // namespace ws
diff --git a/services/ui/ws/window_manager_access_policy.cc b/services/ui/ws/window_manager_access_policy.cc
index e38c7ba..451fd98 100644
--- a/services/ui/ws/window_manager_access_policy.cc
+++ b/services/ui/ws/window_manager_access_policy.cc
@@ -142,6 +142,15 @@
          delegate_->HasRootForAccessPolicy(window);
 }
 
+bool WindowManagerAccessPolicy::CanStackAbove(
+    const ServerWindow* above,
+    const ServerWindow* below) const {
+  // This API is for clients. Window managers can perform any arbitrary
+  // reordering of the windows and don't need to go through this constrained
+  // API.
+  return false;
+}
+
 bool WindowManagerAccessPolicy::CanStackAtTop(
     const ServerWindow* window) const {
   // This API is for clients. Window managers can perform any arbitrary
diff --git a/services/ui/ws/window_manager_access_policy.h b/services/ui/ws/window_manager_access_policy.h
index 8e740cd..f15b36a5 100644
--- a/services/ui/ws/window_manager_access_policy.h
+++ b/services/ui/ws/window_manager_access_policy.h
@@ -52,6 +52,8 @@
   bool CanSetHitTestMask(const ServerWindow* window) const override;
   bool CanSetAcceptDrops(const ServerWindow* window) const override;
   bool CanSetAcceptEvents(const ServerWindow* window) const override;
+  bool CanStackAbove(const ServerWindow* above,
+                     const ServerWindow* below) const override;
   bool CanStackAtTop(const ServerWindow* window) const override;
   bool CanSetCursorProperties(const ServerWindow* window) const override;
   bool CanInitiateDragLoop(const ServerWindow* window) const override;
diff --git a/services/ui/ws/window_manager_client_unittest.cc b/services/ui/ws/window_manager_client_unittest.cc
index 4a5896f9..6362f4cc 100644
--- a/services/ui/ws/window_manager_client_unittest.cc
+++ b/services/ui/ws/window_manager_client_unittest.cc
@@ -54,6 +54,7 @@
       std::unique_ptr<std::vector<uint8_t>>* new_data) override {
     return false;
   }
+  void OnWmSetCanFocus(aura::Window* window, bool can_focus) override {}
   aura::Window* OnWmCreateTopLevelWindow(
       ui::mojom::WindowType window_type,
       std::map<std::string, std::vector<uint8_t>>* properties) override {
diff --git a/services/ui/ws/window_server_test_base.cc b/services/ui/ws/window_server_test_base.cc
index bee909e..c6d4ee1bf 100644
--- a/services/ui/ws/window_server_test_base.cc
+++ b/services/ui/ws/window_server_test_base.cc
@@ -172,6 +172,12 @@
              : true;
 }
 
+void WindowServerTestBase::OnWmSetCanFocus(aura::Window* window,
+                                           bool can_focus) {
+  if (window_manager_delegate_)
+    window_manager_delegate_->OnWmSetCanFocus(window, can_focus);
+}
+
 aura::Window* WindowServerTestBase::OnWmCreateTopLevelWindow(
     ui::mojom::WindowType window_type,
     std::map<std::string, std::vector<uint8_t>>* properties) {
diff --git a/services/ui/ws/window_server_test_base.h b/services/ui/ws/window_server_test_base.h
index a2a72e5..e4a6e65 100644
--- a/services/ui/ws/window_server_test_base.h
+++ b/services/ui/ws/window_server_test_base.h
@@ -94,6 +94,7 @@
       aura::Window* window,
       const std::string& name,
       std::unique_ptr<std::vector<uint8_t>>* new_data) override;
+  void OnWmSetCanFocus(aura::Window* window, bool can_focus) override;
   aura::Window* OnWmCreateTopLevelWindow(
       ui::mojom::WindowType window_type,
       std::map<std::string, std::vector<uint8_t>>* properties) override;
diff --git a/services/ui/ws/window_tree.cc b/services/ui/ws/window_tree.cc
index 1fb3e48..55838d3 100644
--- a/services/ui/ws/window_tree.cc
+++ b/services/ui/ws/window_tree.cc
@@ -1282,6 +1282,9 @@
                                Id window_id,
                                Id relative_window_id,
                                mojom::OrderDirection direction) {
+  // TODO(erg): This implementation allows reordering two windows that are
+  // children of a parent window which the two implementations can't see. There
+  // should be a security check to prevent this.
   bool success = false;
   ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id));
   ServerWindow* relative_window =
@@ -1545,10 +1548,20 @@
 void WindowTree::SetCanFocus(Id transport_window_id, bool can_focus) {
   ServerWindow* window =
       GetWindowByClientId(ClientWindowId(transport_window_id));
-  // TODO(sky): there should be an else case (it shouldn't route to wm and
-  // policy allows, then set_can_focus).
-  if (window && ShouldRouteToWindowManager(window))
+  if (!window) {
+    DVLOG(1) << "SetCanFocus failed (invalid id)";
+    return;
+  }
+
+  if (ShouldRouteToWindowManager(window)) {
+    WindowManagerDisplayRoot* display_root =
+        GetWindowManagerDisplayRoot(window);
+    WindowTree* wm_tree = display_root->window_manager_state()->window_tree();
+    wm_tree->window_manager_internal_->WmSetCanFocus(transport_window_id,
+                                                     can_focus);
+  } else if (access_policy_->CanSetFocus(window)) {
     window->set_can_focus(can_focus);
+  }
 }
 
 void WindowTree::SetCanAcceptEvents(Id transport_window_id,
@@ -1596,6 +1609,64 @@
       wm_tree->ClientWindowIdForWindow(window).id);
 }
 
+void WindowTree::StackAbove(uint32_t change_id, Id above_id, Id below_id) {
+  ServerWindow* above = GetWindowByClientId(ClientWindowId(above_id));
+  if (!above) {
+    DVLOG(1) << "StackAtTop failed (invalid above id)";
+    client()->OnChangeCompleted(change_id, false);
+    return;
+  }
+
+  ServerWindow* below = GetWindowByClientId(ClientWindowId(below_id));
+  if (!below) {
+    DVLOG(1) << "StackAtTop failed (invalid below id)";
+    client()->OnChangeCompleted(change_id, false);
+    return;
+  }
+
+  if (!access_policy_->CanStackAbove(above, below)) {
+    DVLOG(1) << "StackAtTop failed (access denied)";
+    client()->OnChangeCompleted(change_id, false);
+    return;
+  }
+
+  ServerWindow* parent = above->parent();
+  ServerWindow* below_parent = below->parent();
+  if (!parent) {
+    DVLOG(1) << "StackAtTop failed (above unparented)";
+    client()->OnChangeCompleted(change_id, false);
+    return;
+  }
+  if (!below_parent) {
+    DVLOG(1) << "StackAtTop failed (below unparented)";
+    client()->OnChangeCompleted(change_id, false);
+    return;
+  }
+  if (parent != below_parent) {
+    DVLOG(1) << "StackAtTop failed (windows have different parents)";
+    client()->OnChangeCompleted(change_id, false);
+    return;
+  }
+
+  WindowManagerDisplayRoot* display_root = GetWindowManagerDisplayRoot(above);
+  if (!display_root) {
+    DVLOG(1) << "StackAtTop (no display root)";
+    client()->OnChangeCompleted(change_id, false);
+    return;
+  }
+
+  // Window reordering assumes that it is the owner of parent who is sending
+  // the message, and does not deal gracefully with other clients reordering
+  // their windows. So tell the window manager to send us a reorder message.
+  WindowTree* wm_tree = display_root->window_manager_state()->window_tree();
+  const uint32_t wm_change_id =
+      window_server_->GenerateWindowManagerChangeId(this, change_id);
+  wm_tree->window_manager_internal_->WmStackAbove(
+      wm_change_id,
+      wm_tree->ClientWindowIdForWindow(above).id,
+      wm_tree->ClientWindowIdForWindow(below).id);
+}
+
 void WindowTree::StackAtTop(uint32_t change_id, Id window_id) {
   ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id));
   if (!window) {
diff --git a/services/ui/ws/window_tree.h b/services/ui/ws/window_tree.h
index cf0e3795..7ccf7d01 100644
--- a/services/ui/ws/window_tree.h
+++ b/services/ui/ws/window_tree.h
@@ -445,6 +445,7 @@
   void SetCanAcceptDrops(Id window_id, bool accepts_drops) override;
   void SetHitTestMask(Id transport_window_id,
                       const base::Optional<gfx::Rect>& mask) override;
+  void StackAbove(uint32_t change_id, Id above_id, Id below_id) override;
   void StackAtTop(uint32_t change_id, Id window_id) override;
   void GetWindowManagerClient(
       mojo::AssociatedInterfaceRequest<mojom::WindowManagerClient> internal)
diff --git a/services/ui/ws/window_tree_client_unittest.cc b/services/ui/ws/window_tree_client_unittest.cc
index e06fefb..be83a28 100644
--- a/services/ui/ws/window_tree_client_unittest.cc
+++ b/services/ui/ws/window_tree_client_unittest.cc
@@ -457,6 +457,7 @@
       const base::Optional<std::vector<uint8_t>>& value) override {
     window_manager_client_->WmResponse(change_id, false);
   }
+  void WmSetCanFocus(uint32_t window_id, bool can_focus) override {}
   void WmCreateTopLevelWindow(
       uint32_t change_id,
       ClientSpecificId requesting_client_id,
@@ -476,6 +477,10 @@
   }
   void WmCancelMoveLoop(uint32_t window_id) override { NOTIMPLEMENTED(); }
   void WmDeactivateWindow(uint32_t window_id) override { NOTIMPLEMENTED(); }
+  void WmStackAbove(uint32_t change_id, uint32_t above_id,
+                    uint32_t below_id) override {
+    NOTIMPLEMENTED();
+  }
   void WmStackAtTop(uint32_t change_id, uint32_t window_id) override {
     NOTIMPLEMENTED();
   }
diff --git a/skia/OWNERS b/skia/OWNERS
index 1364386..8a43f21 100644
--- a/skia/OWNERS
+++ b/skia/OWNERS
@@ -14,3 +14,5 @@
 senorblanco@chromium.org
 sugoi@google.com
 thakis@chromium.org
+
+# COMPONENT: Internals>Skia
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index 5c58276d..8ba4c27 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -345,7 +345,7 @@
           "--upload-results",
           "--output-format=chartjson",
           "--browser=android-chromium",
-          "--story-filter load:search:google",
+          "--story-filter=load:search:google",
           "--extra-browser-args \"--enable-heap-profiler\""
         ],
         "isolate_name": "telemetry_perf_tests",
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 740fa01..dc0dfae 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -1993,7 +1993,8 @@
           "telemetry_unittests_run"
         ],
         "swarming": {
-          "can_use_on_swarming_builders": false
+          "can_use_on_swarming_builders": false,
+          "shards": 2
         }
       }
     ]
@@ -4479,7 +4480,8 @@
           "telemetry_unittests_run"
         ],
         "swarming": {
-          "can_use_on_swarming_builders": true
+          "can_use_on_swarming_builders": true,
+          "shards": 2
         }
       }
     ],
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index 710920b..b0d76dbd 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -378,7 +378,8 @@
           "telemetry_unittests_run"
         ],
         "swarming": {
-          "can_use_on_swarming_builders": true
+          "can_use_on_swarming_builders": true,
+          "shards": 2
         }
       }
     ]
@@ -735,7 +736,8 @@
           "telemetry_unittests_run"
         ],
         "swarming": {
-          "can_use_on_swarming_builders": true
+          "can_use_on_swarming_builders": true,
+          "shards": 2
         }
       }
     ]
@@ -1081,7 +1083,8 @@
           "telemetry_unittests_run"
         ],
         "swarming": {
-          "can_use_on_swarming_builders": true
+          "can_use_on_swarming_builders": true,
+          "shards": 2
         }
       }
     ]
@@ -1427,7 +1430,8 @@
           "telemetry_unittests_run"
         ],
         "swarming": {
-          "can_use_on_swarming_builders": true
+          "can_use_on_swarming_builders": true,
+          "shards": 2
         }
       }
     ]
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json
index ae76304..957053f 100644
--- a/testing/buildbot/chromium.win.json
+++ b/testing/buildbot/chromium.win.json
@@ -472,7 +472,8 @@
           "telemetry_unittests_run"
         ],
         "swarming": {
-          "can_use_on_swarming_builders": true
+          "can_use_on_swarming_builders": true,
+          "shards": 2
         }
       }
     ],
@@ -1390,7 +1391,8 @@
           "telemetry_unittests_run"
         ],
         "swarming": {
-          "can_use_on_swarming_builders": true
+          "can_use_on_swarming_builders": true,
+          "shards": 2
         }
       }
     ],
@@ -1780,7 +1782,8 @@
           "telemetry_unittests_run"
         ],
         "swarming": {
-          "can_use_on_swarming_builders": true
+          "can_use_on_swarming_builders": true,
+          "shards": 2
         }
       }
     ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
index e3e3731..9ae1e63 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
@@ -30,29 +30,8 @@
 
 # https://crbug.com/625765: Need to solve duplicate output from
 # WebFrameTestClient::willSendRequest() that causes text failures.
-crbug.com/625765 http/tests/cache/iframe-304-crash.html [ Failure ]
-crbug.com/625765 http/tests/history/post-replace-state-reload.html [ Failure ]
 crbug.com/625765 http/tests/loading/redirect-methods.html [ Crash Failure ]
-crbug.com/625765 http/tests/navigation/location-reload-after-post.php [ Failure ]
-crbug.com/625765 http/tests/security/XFrameOptions/x-frame-options-allowall.html [ Failure ]
-crbug.com/625765 http/tests/security/XFrameOptions/x-frame-options-invalid.html [ Failure ]
-crbug.com/625765 http/tests/security/XFrameOptions/x-frame-options-multiple-headers-sameorigin-allow.html [ Failure ]
-crbug.com/625765 http/tests/security/XFrameOptions/x-frame-options-none.html [ Failure ]
-crbug.com/625765 http/tests/security/XFrameOptions/x-frame-options-parent-same-origin-allow.html [ Failure ]
-crbug.com/625765 fast/loader/main-document-url-for-non-http-loads.html [ Failure ]
-crbug.com/625765 external/wpt/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-003.html [ Failure ]
-crbug.com/625765 virtual/stable/http/tests/navigation/location-reload-after-post.php [ Failure ]
-crbug.com/625765 virtual/mojo-loading/http/tests/cache/iframe-304-crash.html [ Failure ]
-crbug.com/625765 virtual/mojo-loading/http/tests/history/post-replace-state-reload.html [ Failure ]
 crbug.com/625765 virtual/mojo-loading/http/tests/loading/redirect-methods.html [ Crash Failure ]
-crbug.com/625765 virtual/mojo-loading/http/tests/navigation/location-reload-after-post.php [ Failure ]
-crbug.com/625765 virtual/mojo-loading/http/tests/security/XFrameOptions/x-frame-options-allowall.html [ Failure ]
-crbug.com/625765 virtual/mojo-loading/http/tests/security/XFrameOptions/x-frame-options-deny.html [ Failure ]
-crbug.com/625765 virtual/mojo-loading/http/tests/security/XFrameOptions/x-frame-options-invalid.html [ Failure ]
-crbug.com/625765 virtual/mojo-loading/http/tests/security/XFrameOptions/x-frame-options-multiple-headers-conflict.html [ Failure ]
-crbug.com/625765 virtual/mojo-loading/http/tests/security/XFrameOptions/x-frame-options-multiple-headers-sameorigin-allow.html [ Failure ]
-crbug.com/625765 virtual/mojo-loading/http/tests/security/XFrameOptions/x-frame-options-none.html [ Failure ]
-crbug.com/625765 virtual/mojo-loading/http/tests/security/XFrameOptions/x-frame-options-parent-same-origin-allow.html [ Failure ]
 
 # https://crbug.com/555418: Move `X-Frame-Options` and CSP's `frame-ancestor`
 # checks up out of the renderer.
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 489d3246..6a38446 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -110,8 +110,6 @@
 
 crbug.com/644433 virtual/gpu/fast/canvas/OffscreenCanvas-2d-pattern-in-worker.html [ Failure ]
 
-crbug.com/683312 virtual/gpu/fast/canvas/canvas-pattern-no-repeat-with-transformations.html [ NeedsRebaseline ]
-
 crbug.com/645389 [ Win ] virtual/gpu/fast/canvas/canvas-hit-regions-fallback-element-test.html [ Timeout ]
 crbug.com/645389 [ Win ] virtual/gpu/fast/canvas/canvas-hit-regions-event-test.html [ Timeout ]
 crbug.com/645389 [ Win ] fast/canvas/canvas-hit-regions-fallback-element-test.html [ Timeout ]
@@ -153,9 +151,6 @@
 # Added 2016-12-15
 crbug.com/674468 [ Trusty ] compositing/reflections/nested-reflection-transition.html [ Pass Failure ]
 
-# ====== Paint team owned tests to here ======
-crbug.com/681369 editing/selection/select-delete-in-event-handler.html [ NeedsRebaseline ]
-
 
 # ====== LayoutNG-only failures from here ======
 # LayoutNG - is a new layout system for Blink.
@@ -694,8 +689,6 @@
 
 crbug.com/617152 external/wpt/mediacapture-streams/GUM-impossible-constraint.https.html [ Skip ]
 
-Bug(none) virtual/stable/paint/invalidation/control-clip.html [ NeedsRebaseline ]
-
 crbug.com/417782 [ Linux Win ] virtual/rootlayerscrolls/fast/scrolling/fractional-scroll-offset-fixed-position-non-composited.html [ Failure ]
 crbug.com/492664 [ Linux ] external/csswg-test/css-writing-modes-3/box-offsets-rel-pos-vlr-005.xht [ Failure ]
 crbug.com/492664 [ Linux ] external/csswg-test/css-writing-modes-3/box-offsets-rel-pos-vrl-004.xht [ Failure ]
@@ -764,8 +757,6 @@
 
 crbug.com/636239 [ Win7 ] media/video-zoom-controls.html [ Failure ]
 
-crbug.com/684923 inspector/sources/debugger-async/async-callstack-promises.html [ NeedsManualRebaseline ]
-
 crbug.com/432129 fast/html/marquee-scroll.html [ Failure Pass ]
 crbug.com/326139 crbug.com/390125 media/video-frame-accurate-seek.html [ Failure Pass ]
 crbug.com/248938 virtual/threaded/animations/animation-iteration-event-destroy-renderer.html [ Pass Timeout ]
@@ -777,53 +768,6 @@
 
 crbug.com/659123 [ Mac ] fast/css/text-overflow-ellipsis-button.html [ Pass Failure ]
 
-crbug.com/35697 [ Mac Win ] fast/table/backgr_border-table-cell-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_border-table-cell.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_border-table-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_border-table-column-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_border-table-column-group-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_border-table-column-group.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_border-table-column.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_border-table-quirks-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_border-table-quirks.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_border-table-row-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_border-table-row-group-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_border-table-row-group.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_border-table-row.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_border-table.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_layers-hide-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_layers-hide.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_layers-opacity-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_layers-opacity.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_layers-show-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_layers-show.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_position-table-cell-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_position-table-cell.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_position-table-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_position-table-column-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_position-table-column-group-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_position-table-column-group.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_position-table-column.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_position-table-row-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_position-table-row-group-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_position-table-row-group.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_position-table-row.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_position-table.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_simple-table-cell-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_simple-table-cell.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_simple-table-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_simple-table-column-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_simple-table-column-group-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_simple-table-column-group.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_simple-table-column.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_simple-table-row-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_simple-table-row-group-collapsed-border.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_simple-table-row-group.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_simple-table-row.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] fast/table/backgr_simple-table.html [ NeedsRebaseline ]
-crbug.com/35697 fast/table/tbody-background-image.html [ NeedsRebaseline ]
-crbug.com/35697 [ Mac Win ] tables/mozilla_expected_failures/marvin/backgr_fixed-bg.html [ NeedsRebaseline ]
-
 # TODO(oshima): Mac Android are currently not supported.
 crbug.com/567837 [ Mac Android ] virtual/scalefactor200withzoom/fast/hidpi/static [ Skip ]
 
@@ -953,9 +897,6 @@
 
 crbug.com/655963 inspector/console/console-dir.html [ NeedsManualRebaseline ]
 
-crbug.com/682574 css3/flexbox/button.html [ NeedsRebaseline ]
-crbug.com/682574 fast/forms/select-popup/popup-menu-appearance-transform.html [ NeedsRebaseline ]
-
 crbug.com/405389 external/csswg-test/css-shapes-1/shape-outside/supported-shapes/polygon/shape-outside-polygon-017.html [ Failure ]
 crbug.com/424365 external/csswg-test/css-shapes-1/shape-outside/shape-image/shape-image-010.html [ Failure ]
 crbug.com/424365 external/csswg-test/css-shapes-1/shape-outside/shape-image/shape-image-024.html [ Failure ]
@@ -2326,6 +2267,8 @@
 # When WebAssembly is exposed in V8 (soon), this test has the wrong number of expected Object.getOwnPropertyNames() for global object.
 crbug.com/575167 external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions.html [ NeedsManualRebaseline ]
 
+crbug.com/685713 virtual/enable_wasm/http/tests/wasm/wasm_serialization_tests.html [ Pass Failure ]
+
 crbug.com/681468 fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom125.html [ Failure Pass ]
 crbug.com/681468 fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom200.html [ Failure Pass ]
 
diff --git a/third_party/WebKit/LayoutTests/compositing/iframes/floating-self-painting-frame-complex-expected.html b/third_party/WebKit/LayoutTests/compositing/iframes/floating-self-painting-frame-complex-expected.html
new file mode 100644
index 0000000..5d16b68
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/iframes/floating-self-painting-frame-complex-expected.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<iframe style="width: 400px; height: 500px; border: none"
+  srcdoc="<div style='width: 300px; height:400px; background: blue'></div>"></iframe>
diff --git a/third_party/WebKit/LayoutTests/compositing/iframes/floating-self-painting-frame-complex.html b/third_party/WebKit/LayoutTests/compositing/iframes/floating-self-painting-frame-complex.html
new file mode 100644
index 0000000..bb0aa82
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/iframes/floating-self-painting-frame-complex.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<script src="../../resources/run-after-layout-and-paint.js"></script>
+<!-- This is similar to floating-self-painting-frame.html, but contains multiple
+containing blocks and sibling blocks in which the floating objects overhangs
+and intrudes. Tests shouldPaint flag is set on at most one ancestor containing
+block. Passes if no crash (on display items with duplicated ids because the
+iframe would be painted multiple times). -->
+<style>div {height: 100px; background-color: white;}</style>
+<div>
+  <div>
+    <div>
+      <iframe id="target" style="float: left; width: 400px; height: 100px; border: none"
+         srcdoc="<div style='width: 300px; height:400px; background: blue'></div>"></iframe>
+      <div></div>
+      <div></div>
+    </div>
+  </div>
+</div>
+<script>
+if (window.internals)
+  window.internals.settings.setPreferCompositingToLCDTextEnabled(true);
+runAfterLayoutAndPaint(function() {
+  target.style.height = "500px";
+}, true);
+</script>
diff --git a/third_party/WebKit/LayoutTests/editing/selection/select-delete-in-event-handler-expected.txt b/third_party/WebKit/LayoutTests/editing/selection/select-delete-in-event-handler-expected.txt
index f4b104d4..7898192 100644
--- a/third_party/WebKit/LayoutTests/editing/selection/select-delete-in-event-handler-expected.txt
+++ b/third_party/WebKit/LayoutTests/editing/selection/select-delete-in-event-handler-expected.txt
@@ -1 +1 @@
-<HEAD></HEAD><BODY>Passes if it does not crash. <SCRIPT> function selectionChangeHandler() { document.designMode = "on"; } document.addEventListener("selectionchange", selectionChangeHandler, true); var focusInActive = false; function focusInHandler() { if (focusInActive) return; focusInActive = true; var oElement = event.srcElement; oElement.innerHTML = 'a'; document.execCommand("SelectAll", false, false); } function cleanup() { while (true) { var oe = document.getElementsByTagName("*"); if (oe.length <= 1) return; for (var i = 0; i < oe.length; i++) { var o = oe.item(i); if (!o.firstElementChild && o != document.documentElement) { var p = o.parentNode; p.replaceChild(document.createTextNode( "<" + o.tagName + ">" + o.textContent + "</" + o.tagName + ">"), o); } } } } window.onload = function() { cleanup(); document.addEventListener("DOMFocusIn", focusInHandler, false); setTimeout(function() { if (eventSender) { eventSender.mouseMoveTo(100, 100); eventSender.mouseDown(); setTimeout(function() { eventSender.mouseMoveTo(100, 101); eventSender.mouseUp(); if (testRunner) testRunner.notifyDone(); }, 0); } }, 0); }; if (testRunner) { testRunner.waitUntilDone(); testRunner.dumpAsText(); } </SCRIPT> </BODY>
+a
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/rubybase-children-moved-crash-2-expected.txt b/third_party/WebKit/LayoutTests/fast/block/float/rubybase-children-moved-crash-2-expected.txt
new file mode 100644
index 0000000..0bfa3ce
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/rubybase-children-moved-crash-2-expected.txt
@@ -0,0 +1,3 @@
+crbug.com/683104: Passes if it does not crash.
+
+Text  
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/rubybase-children-moved-crash-2.html b/third_party/WebKit/LayoutTests/fast/block/float/rubybase-children-moved-crash-2.html
new file mode 100644
index 0000000..3b9887e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/rubybase-children-moved-crash-2.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<style id="style">
+.float{float:left;}
+.list-item{display:list-item;}
+</style>
+<p>crbug.com/683104: Passes if it does not crash.</p>
+<ruby id="ruby">
+  <rb>
+    <div class="float list-item"></div>
+    Text
+    <input class="list-item">
+    <rt id="rt" class="list-item">
+      <rtc></rtc>
+    </rt>
+  </rb>
+</ruby>
+<script>
+  if (window.testRunner)
+    testRunner.dumpAsText();
+  document.body.offsetTop;
+  var oElement = document.getElementById("style");
+  oElement.insertAdjacentHTML('afterbegin', '<summary><_______ZZ(((P%%%%8</summary>');
+  document.execCommand(false);
+  var newElement = document.getElementById("rt");
+  oElement.parentNode.replaceChild(newElement, oElement)
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-enabledforall-expected.txt b/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-enabledforall-expected.txt
new file mode 100644
index 0000000..2a8cea8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-enabledforall-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL Fullscreen enabled for all on URL: resources/feature-policy-fullscreen.html with allowfullscreen = false assert_true: Document.fullscreenEnabled: expected true got false
+FAIL Fullscreen enabled for all on URL: http://localhost:8000/feature-policy/resources/feature-policy-fullscreen.html with allowfullscreen = false assert_true: Document.fullscreenEnabled: expected true got false
+PASS Fullscreen enabled for all on URL: resources/feature-policy-fullscreen.html with allowfullscreen = true 
+PASS Fullscreen enabled for all on URL: http://localhost:8000/feature-policy/resources/feature-policy-fullscreen.html with allowfullscreen = true 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-enabledforall.php b/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-enabledforall.php
index 18f970a..88e9cdbf 100644
--- a/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-enabledforall.php
+++ b/third_party/WebKit/LayoutTests/http/tests/feature-policy/fullscreen-enabledforall.php
@@ -4,8 +4,8 @@
 // found in the LICENSE file.
 
 // This test ensures that fullscreen feature when enabled for all works across
-// origins when allowfullscreen is set. No iframe may call it when
-// allowfullscreen is not set.
+// origins regardless of whether allowfullscreen is set. (Feature policy header
+// takes precedence over the absence of allowfullscreen.)
 
 Header("Feature-Policy: {\"fullscreen\": [\"*\"]}");
 ?>
@@ -32,13 +32,8 @@
           resolve(e.data);
         }, { once: true });
       }).then(function(data) {
-        if (iframe.id === "f2") {
-          assert_true(data.enabled, 'Document.fullscreenEnabled:');
-          assert_equals(data.type, 'change', 'Document.requestFullscreen():');
-        } else {
-          assert_false(data.enabled, 'Document.fullscreenEnabled:');
-          assert_equals(data.type, 'error', 'Document.requestFullscreen():');
-        }
+        assert_true(data.enabled, 'Document.fullscreenEnabled:');
+        assert_equals(data.type, 'change', 'Document.requestFullscreen():');
       });
     }, 'Fullscreen enabled for all on URL: ' + src + ' with allowfullscreen = ' + iframe.allowFullscreen);
   }
diff --git a/third_party/WebKit/LayoutTests/http/tests/feature-policy/resources/feature-policy-fullscreen.html b/third_party/WebKit/LayoutTests/http/tests/feature-policy/resources/feature-policy-fullscreen.html
index 1fe1b74..2516b8c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/feature-policy/resources/feature-policy-fullscreen.html
+++ b/third_party/WebKit/LayoutTests/http/tests/feature-policy/resources/feature-policy-fullscreen.html
@@ -7,8 +7,10 @@
 };
 
 document.onwebkitfullscreenchange = function() {
-  document.webkitExitFullscreen();
-  parent.postMessage({ type: 'change', enabled: document.webkitFullscreenEnabled }, '*');
+  if (document.webkitFullscreenElement) {
+    document.webkitExitFullscreen();
+    parent.postMessage({ type: 'change', enabled: document.webkitFullscreenEnabled }, '*');
+  }
 };
 
 document.addEventListener('keypress', function() {
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/selection/select-delete-in-event-handler-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/editing/selection/select-delete-in-event-handler-expected.txt
new file mode 100644
index 0000000..f4b104d4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/editing/selection/select-delete-in-event-handler-expected.txt
@@ -0,0 +1 @@
+<HEAD></HEAD><BODY>Passes if it does not crash. <SCRIPT> function selectionChangeHandler() { document.designMode = "on"; } document.addEventListener("selectionchange", selectionChangeHandler, true); var focusInActive = false; function focusInHandler() { if (focusInActive) return; focusInActive = true; var oElement = event.srcElement; oElement.innerHTML = 'a'; document.execCommand("SelectAll", false, false); } function cleanup() { while (true) { var oe = document.getElementsByTagName("*"); if (oe.length <= 1) return; for (var i = 0; i < oe.length; i++) { var o = oe.item(i); if (!o.firstElementChild && o != document.documentElement) { var p = o.parentNode; p.replaceChild(document.createTextNode( "<" + o.tagName + ">" + o.textContent + "</" + o.tagName + ">"), o); } } } } window.onload = function() { cleanup(); document.addEventListener("DOMFocusIn", focusInHandler, false); setTimeout(function() { if (eventSender) { eventSender.mouseMoveTo(100, 100); eventSender.mouseDown(); setTimeout(function() { eventSender.mouseMoveTo(100, 101); eventSender.mouseUp(); if (testRunner) testRunner.notifyDone(); }, 0); } }, 0); }; if (testRunner) { testRunner.waitUntilDone(); testRunner.dumpAsText(); } </SCRIPT> </BODY>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-transform-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-transform-expected.png
index c24f3e1..a5b10fa 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-collapsed-border-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-collapsed-border-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-collapsed-border-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-collapsed-border-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-collapsed-border-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-group-collapsed-border-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_border-table-column-group-collapsed-border-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-group-collapsed-border-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-collapsed-border-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-collapsed-border-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-collapsed-border-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-collapsed-border-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-collapsed-border-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-group-collapsed-border-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_border-table-row-group-collapsed-border-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-group-collapsed-border-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-collapsed-border-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide-collapsed-border-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-collapsed-border-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide-collapsed-border-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-collapsed-border-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_layers-hide-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-collapsed-border-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_position-table-collapsed-border-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-collapsed-border-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_position-table-collapsed-border-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-collapsed-border-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-collapsed-border-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-collapsed-border-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-collapsed-border-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-collapsed-border-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-collapsed-border-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-group-collapsed-border-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_position-table-column-group-collapsed-border-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-group-collapsed-border-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_position-table-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_position-table-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-collapsed-border-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-collapsed-border-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-collapsed-border-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-collapsed-border-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-collapsed-border-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-group-collapsed-border-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_position-table-row-group-collapsed-border-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-group-collapsed-border-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-collapsed-border-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-collapsed-border-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-collapsed-border-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-collapsed-border-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-collapsed-border-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-collapsed-border-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-column-group-collapsed-border-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-collapsed-border-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-collapsed-border-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-collapsed-border-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-collapsed-border-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-collapsed-border-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-collapsed-border-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-collapsed-border-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/table/backgr_simple-table-row-group-collapsed-border-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-collapsed-border-expected.txt
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/tbody-background-image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/tbody-background-image-expected.png
new file mode 100644
index 0000000..00eb6ac
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/tbody-background-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/tbody-background-image-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/table/tbody-background-image-expected.txt
new file mode 100644
index 0000000..f244d4d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/tbody-background-image-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x464
+  LayoutBlockFlow {HTML} at (0,0) size 800x464
+    LayoutBlockFlow {BODY} at (8,16) size 784x440
+      LayoutBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 370x19
+          text run at (0,0) width 370: "crbug.com/35697: The image should be tiled across the table."
+      LayoutTable {TABLE} at (0,36) size 784x404
+        LayoutTableSection {TBODY} at (0,0) size 784x404
+          LayoutTableRow {TR} at (0,0) size 784x202
+            LayoutTableCell {TD} at (0,100) size 392x2 [r=0 c=0 rs=1 cs=1]
+            LayoutTableCell {TD} at (392,100) size 392x2 [r=0 c=1 rs=1 cs=1]
+          LayoutTableRow {TR} at (0,202) size 784x202
+            LayoutTableCell {TD} at (0,302) size 392x2 [r=1 c=0 rs=1 cs=1]
+            LayoutTableCell {TD} at (392,302) size 392x2 [r=1 c=1 rs=1 cs=1]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png
index 07da042..3957d38 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-cell-collapsed-border-expected.png
new file mode 100644
index 0000000..4bbfb61
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-cell-expected.png
new file mode 100644
index 0000000..c5b225de
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-collapsed-border-expected.png
new file mode 100644
index 0000000..1b2bf4d8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-collapsed-border-expected.png
new file mode 100644
index 0000000..991ba5bf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-expected.png
new file mode 100644
index 0000000..c9947f8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
new file mode 100644
index 0000000..c91a474
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-group-expected.png
new file mode 100644
index 0000000..d2da6a7a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-expected.png
new file mode 100644
index 0000000..97c2c350
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-quirks-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
new file mode 100644
index 0000000..b636956
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-quirks-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-quirks-expected.png
new file mode 100644
index 0000000..acd701d9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-quirks-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-collapsed-border-expected.png
new file mode 100644
index 0000000..ec08b8d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-expected.png
new file mode 100644
index 0000000..b6f500e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
new file mode 100644
index 0000000..704ad035
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-group-expected.png
new file mode 100644
index 0000000..653682f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_layers-hide-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_layers-hide-collapsed-border-expected.png
new file mode 100644
index 0000000..16a66be
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_layers-hide-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_layers-hide-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_layers-hide-expected.png
new file mode 100644
index 0000000..5785c54
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_layers-hide-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-cell-collapsed-border-expected.png
new file mode 100644
index 0000000..c756d37
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-cell-expected.png
new file mode 100644
index 0000000..068afc0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-collapsed-border-expected.png
new file mode 100644
index 0000000..aa585755
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-collapsed-border-expected.png
new file mode 100644
index 0000000..57143aab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-expected.png
new file mode 100644
index 0000000..33e1bec
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
new file mode 100644
index 0000000..a034446
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-group-expected.png
new file mode 100644
index 0000000..d1c2b480
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-expected.png
new file mode 100644
index 0000000..8986885
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-collapsed-border-expected.png
new file mode 100644
index 0000000..1633403
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-expected.png
new file mode 100644
index 0000000..52bfc05d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
new file mode 100644
index 0000000..1fb1395
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-group-expected.png
new file mode 100644
index 0000000..118fafe9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
new file mode 100644
index 0000000..867aee1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-expected.png
new file mode 100644
index 0000000..104af65
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-collapsed-border-expected.png
new file mode 100644
index 0000000..b9f12c3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-collapsed-border-expected.png
new file mode 100644
index 0000000..426fe1e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-expected.png
new file mode 100644
index 0000000..8c76cfd5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
new file mode 100644
index 0000000..17be6e4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-expected.png
new file mode 100644
index 0000000..c431008b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-expected.png
new file mode 100644
index 0000000..2ea6701b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-collapsed-border-expected.png
new file mode 100644
index 0000000..5b1421d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-expected.png
new file mode 100644
index 0000000..36012dd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
new file mode 100644
index 0000000..a6f3e52
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-expected.png
new file mode 100644
index 0000000..dc795f3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index ceea335..1cd1f32 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-cell-collapsed-border-expected.png
new file mode 100644
index 0000000..1045a33
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-cell-expected.png
new file mode 100644
index 0000000..ed3597ba
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-collapsed-border-expected.png
new file mode 100644
index 0000000..bf67ce4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-expected.png
new file mode 100644
index 0000000..b7c44dd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
new file mode 100644
index 0000000..20a416f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-expected.png
new file mode 100644
index 0000000..3eed2112
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-expected.png
new file mode 100644
index 0000000..6654227
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-collapsed-border-expected.png
new file mode 100644
index 0000000..67b1987
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-expected.png
new file mode 100644
index 0000000..c7d8515
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
new file mode 100644
index 0000000..a2bd2bd0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-group-expected.png
new file mode 100644
index 0000000..7e2fbee8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_layers-hide-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_layers-hide-expected.png
new file mode 100644
index 0000000..4b5327e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_layers-hide-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_layers-show-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_layers-show-collapsed-border-expected.png
new file mode 100644
index 0000000..4bd2deb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_layers-show-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_layers-show-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_layers-show-expected.png
new file mode 100644
index 0000000..5e7d2bc6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_layers-show-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-collapsed-border-expected.png
new file mode 100644
index 0000000..553c171
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-expected.png
new file mode 100644
index 0000000..27e8f86
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-collapsed-border-expected.png
new file mode 100644
index 0000000..f460de8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-expected.png
new file mode 100644
index 0000000..85c573b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
new file mode 100644
index 0000000..e49cf75
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-group-expected.png
new file mode 100644
index 0000000..844b07dd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-collapsed-border-expected.png
new file mode 100644
index 0000000..a9a6454
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-expected.png
new file mode 100644
index 0000000..29529b57
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
new file mode 100644
index 0000000..1e5123b1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-group-expected.png
new file mode 100644
index 0000000..894d3ef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
new file mode 100644
index 0000000..094beb62
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-expected.png
new file mode 100644
index 0000000..a7f9b81
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png
new file mode 100644
index 0000000..4398428
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-collapsed-border-expected.png
new file mode 100644
index 0000000..6cffd7e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-expected.png
new file mode 100644
index 0000000..2c309b9a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
new file mode 100644
index 0000000..6879c80
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-expected.png
new file mode 100644
index 0000000..7e95424
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png
new file mode 100644
index 0000000..39bdb26
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-collapsed-border-expected.png
new file mode 100644
index 0000000..3b8d73a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-expected.png
new file mode 100644
index 0000000..4aa50b2c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
new file mode 100644
index 0000000..9f77de4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-expected.png
new file mode 100644
index 0000000..40dac59
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
new file mode 100644
index 0000000..7ef0c15
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-collapsed-border-expected.png
new file mode 100644
index 0000000..fab80b5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-collapsed-border-expected.txt
new file mode 100644
index 0000000..173fa98e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-collapsed-border-expected.txt
@@ -0,0 +1,83 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 639
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x639 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x639.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x616.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 393x17
+          text run at (0,0) width 393: "crbug.com/35679: Background on 'table-cell'"
+      LayoutTable {TABLE} at (0,32.20) size 586x438 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 586x22
+          LayoutText {#text} at (148,0) size 290x22
+            text run at (148,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (2,28) size 581x101
+          LayoutTableRow {TR} at (0,0) size 581x101
+            LayoutTableCell {TH} at (0,34) size 137x33 [border: (3px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (44,4) size 46x22
+                text run at (44,4) width 46: "TH A"
+            LayoutTableCell {TH} at (137,32) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (344,37) size 123x27 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,4) size 46x22
+                text run at (42,4) width 46: "TH C"
+            LayoutTableCell {TH} at (467,37) size 114x27 [border: (3px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,4) size 45x22
+                text run at (34,4) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (2,319) size 581x116
+          LayoutTableRow {TR} at (0,0) size 581x116
+            LayoutTableCell {TD} at (0,41) size 344x33 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (4,8) size 47x22
+                text run at (4,8) width 47: "TD M"
+            LayoutTableCell {TD} at (344,44) size 123x27 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (467,44) size 114x27 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (2,129) size 581x190
+          LayoutTableRow {TR} at (0,0) size 581x107
+            LayoutTableCell {TD} at (0,76) size 137x37 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (137,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (344,41) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (467,41) size 114x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 581x83
+            LayoutTableCell {TD} at (137,136) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (344,136) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (467,136) size 114x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,483.20) size 769x15
+        LayoutText {#text} at (0,0) size 164x15
+          text run at (0,0) width 164: "Two cells are styled."
+      LayoutBlockFlow {P} at (0,511.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "There should be three aqua stripes just inside the top and left padding edges of cell E."
+      LayoutBlockFlow {P} at (0,539.20) size 769x15
+        LayoutText {#text} at (0,0) size 710x15
+          text run at (0,0) width 710: "There should be three aqua stripes just inside the bottom and right padding edges of Cell M"
+      LayoutBlockFlow {DIV} at (0,567.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,601.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-expected.png
new file mode 100644
index 0000000..de54438f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-expected.txt
new file mode 100644
index 0000000..a05a9ed
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-expected.txt
@@ -0,0 +1,83 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 675
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x675 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x675.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x652.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 393x17
+          text run at (0,0) width 393: "crbug.com/35679: Background on 'table-cell'"
+      LayoutTable {TABLE} at (0,32.20) size 626x474 [color=#FFFFFF] [border: (5px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 626x22
+          LayoutText {#text} at (167,0) size 292x22
+            text run at (167,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (5,27) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (5,347) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (5,141) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [bgcolor=#000000] [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,519.20) size 769x15
+        LayoutText {#text} at (0,0) size 164x15
+          text run at (0,0) width 164: "Two cells are styled."
+      LayoutBlockFlow {P} at (0,547.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "There should be three aqua stripes just inside the top and left padding edges of cell E."
+      LayoutBlockFlow {P} at (0,575.20) size 769x15
+        LayoutText {#text} at (0,0) size 710x15
+          text run at (0,0) width 710: "There should be three aqua stripes just inside the bottom and right padding edges of Cell M"
+      LayoutBlockFlow {DIV} at (0,603.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,637.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-collapsed-border-expected.png
new file mode 100644
index 0000000..b86ae61
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-collapsed-border-expected.txt
new file mode 100644
index 0000000..5099972
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-collapsed-border-expected.txt
@@ -0,0 +1,77 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x570
+  LayoutBlockFlow {HTML} at (0,0) size 800x570.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 784x547.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 784x17
+        LayoutText {#text} at (0,0) size 192x17
+          text run at (0,0) width 192: "Background on 'table'"
+      LayoutBlockFlow {P} at (0,32.20) size 784x15
+        LayoutText {#text} at (0,0) size 640x15
+          text run at (0,0) width 640: "There should be three aqua stripes just inside the bottom and right table borders."
+      LayoutTable {TABLE} at (0,60.20) size 586x438 [color=#FFFFFF] [bgcolor=#000000] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 586x22
+          LayoutText {#text} at (148,0) size 290x22
+            text run at (148,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (2,28) size 581x101
+          LayoutTableRow {TR} at (0,0) size 581x101
+            LayoutTableCell {TH} at (0,34) size 137x33 [border: (3px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (44,4) size 46x22
+                text run at (44,4) width 46: "TH A"
+            LayoutTableCell {TH} at (137,32) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (344,37) size 123x27 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,4) size 46x22
+                text run at (42,4) width 46: "TH C"
+            LayoutTableCell {TH} at (467,37) size 114x27 [border: (3px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,4) size 45x22
+                text run at (34,4) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (2,319) size 581x116
+          LayoutTableRow {TR} at (0,0) size 581x116
+            LayoutTableCell {TD} at (0,41) size 344x33 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (4,8) size 47x22
+                text run at (4,8) width 47: "TD M"
+            LayoutTableCell {TD} at (344,44) size 123x27 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (467,44) size 114x27 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (2,129) size 581x190
+          LayoutTableRow {TR} at (0,0) size 581x107
+            LayoutTableCell {TD} at (0,76) size 137x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (137,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (344,41) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (467,41) size 114x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 581x83
+            LayoutTableCell {TD} at (137,136) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (344,136) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (467,136) size 114x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {DIV} at (0,498.20) size 784x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,532.20) size 784x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-collapsed-border-expected.png
new file mode 100644
index 0000000..7dcb611
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-collapsed-border-expected.txt
new file mode 100644
index 0000000..6f20210
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-collapsed-border-expected.txt
@@ -0,0 +1,96 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 815
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x815 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x815.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x792.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 411x17
+          text run at (0,0) width 411: "crbug.com/35697: Background on 'table-column'"
+      LayoutTable {TABLE} at (0,32.20) size 588x436 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 588x22
+          LayoutText {#text} at (149,0) size 290x22
+            text run at (149,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000] [border: (9px dashed #FFFFFF)]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (2,28) size 584x100
+          LayoutTableRow {TR} at (0,0) size 584x100
+            LayoutTableCell {TH} at (0,33) size 137x33 [border: (3px dashed #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (44,4) size 46x22
+                text run at (44,4) width 46: "TH A"
+            LayoutTableCell {TH} at (137,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (344,35) size 125x29 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,4) size 46x22
+                text run at (42,4) width 46: "TH C"
+            LayoutTableCell {TH} at (469,37) size 115x26 [border: (2px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (36,3) size 45x22
+                text run at (36,3) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (2,318) size 584x115
+          LayoutTableRow {TR} at (0,0) size 584x115
+            LayoutTableCell {TD} at (0,41) size 344x33 [border: (7px dashed #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (4,8) size 47x22
+                text run at (4,8) width 47: "TD M"
+            LayoutTableCell {TD} at (344,44) size 125x27 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,2) size 46x22
+                text run at (6,2) width 46: "TD O"
+            LayoutTableCell {TD} at (469,44) size 115x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (4,2) size 44x22
+                text run at (4,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (2,128) size 584x190
+          LayoutTableRow {TR} at (0,0) size 584x107
+            LayoutTableCell {TD} at (0,76) size 137x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (137,36) size 207x35 [border: (7px dashed #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (344,39) size 125x29 [border: (3px dashed #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,4) size 46x22
+                text run at (6,4) width 46: "TD G"
+            LayoutTableCell {TD} at (469,41) size 115x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (4,2) size 45x22
+                text run at (4,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 584x83
+            LayoutTableCell {TD} at (137,133) size 207x31 [border: (5px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,6) size 42x22
+                text run at (8,6) width 42: "TD J"
+            LayoutTableCell {TD} at (344,135) size 125x27 [border: (3px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,4) size 45x22
+                text run at (6,4) width 45: "TD K"
+            LayoutTableCell {TD} at (469,136) size 115x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (4,2) size 43x22
+                text run at (4,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,481.20) size 769x15
+        LayoutText {#text} at (0,0) size 196x15
+          text run at (0,0) width 196: "Three columns are styled."
+      LayoutBlockFlow {P} at (0,509.20) size 769x105
+        LayoutText {#text} at (0,0) size 765x105
+          text run at (0,0) width 742: "In the first column, there should be three vertical stripes along the padding edge of the first"
+          text run at (0,15) width 726: "cell, continuing down through the column. (In cell E, the aqua stripe will be obscured by the"
+          text run at (0,30) width 765: "thicker right border.) The stripes will cut across cell E as well, but will be further obscured by"
+          text run at (0,45) width 749: "its thick border. In the border-collapsed table, the same will happen to the vertical stripes in"
+          text run at (0,60) width 765: "cell A due to cell B's thick border. The stripes should continue in the last cell, turning a right"
+          text run at (0,75) width 757: "angle to the left into three aqua stripes along the bottom border edge of the last cell. The last"
+          text run at (0,90) width 539: "cell (M) should not have three vertical stripes along its right edge."
+      LayoutBlockFlow {P} at (0,627.20) size 769x45
+        LayoutText {#text} at (0,0) size 749x45
+          text run at (0,0) width 749: "In the second column, three vertical strips should run along the right of the first three cells,"
+          text run at (0,15) width 742: "aligning along cell F's right padding edge. (The stripes will be partially obscured by cell B's"
+          text run at (0,30) width 110: "thick border.)"
+      LayoutBlockFlow {P} at (0,685.20) size 769x45
+        LayoutText {#text} at (0,0) size 765x45
+          text run at (0,0) width 765: "In the third column, there should be three vertical stripes should run across the top of the first"
+          text run at (0,15) width 710: "cell and down the left of the column, aligning along cell K's left padding edge. In border-"
+          text run at (0,30) width 562: "collapse mode, they will be partially obscured by cell B's thick border."
+      LayoutBlockFlow {DIV} at (0,743.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,777.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-expected.png
new file mode 100644
index 0000000..eaf2d2e1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-expected.txt
new file mode 100644
index 0000000..b99f0fc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-expected.txt
@@ -0,0 +1,96 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 849
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x849 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x849.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x826.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 411x17
+          text run at (0,0) width 411: "crbug.com/35679: Background on 'table-column'"
+      LayoutTable {TABLE} at (0,32.20) size 630x470 [color=#FFFFFF] [border: (3px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 630x22
+          LayoutText {#text} at (169,0) size 292x22
+            text run at (169,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000] [border: (9px dashed #FFFFFF)]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (3,25) size 624x114
+          LayoutTableRow {TR} at (0,7) size 624x100
+            LayoutTableCell {TH} at (7,40) size 138x34 [border: (5px dashed #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (46,6) size 46x22
+                text run at (46,6) width 46: "TH A"
+            LayoutTableCell {TH} at (152,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (379,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (504,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (3,345) size 624x122
+          LayoutTableRow {TR} at (0,0) size 624x115
+            LayoutTableCell {TD} at (7,40) size 365x34 [border: (5px dashed #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (6,6) size 47x22
+                text run at (6,6) width 47: "TD M"
+            LayoutTableCell {TD} at (379,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (504,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (3,139) size 624x206
+          LayoutTableRow {TR} at (0,0) size 624x108
+            LayoutTableCell {TD} at (7,74) size 138x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (152,33) size 220x42 [border: (9px dashed #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (10,10) size 43x22
+                text run at (10,10) width 43: "TD F"
+            LayoutTableCell {TD} at (379,37) size 118x34 [border: (5px dashed #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 46x22
+                text run at (6,6) width 46: "TD G"
+            LayoutTableCell {TD} at (504,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 624x84
+            LayoutTableCell {TD} at (152,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (379,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (504,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,515.20) size 769x15
+        LayoutText {#text} at (0,0) size 196x15
+          text run at (0,0) width 196: "Three columns are styled."
+      LayoutBlockFlow {P} at (0,543.20) size 769x105
+        LayoutText {#text} at (0,0) size 765x105
+          text run at (0,0) width 742: "In the first column, there should be three vertical stripes along the padding edge of the first"
+          text run at (0,15) width 726: "cell, continuing down through the column. (In cell E, the aqua stripe will be obscured by the"
+          text run at (0,30) width 765: "thicker right border.) The stripes will cut across cell E as well, but will be further obscured by"
+          text run at (0,45) width 749: "its thick border. In the border-collapsed table, the same will happen to the vertical stripes in"
+          text run at (0,60) width 765: "cell A due to cell B's thick border. The stripes should continue in the last cell, turning a right"
+          text run at (0,75) width 757: "angle to the left into three aqua stripes along the bottom border edge of the last cell. The last"
+          text run at (0,90) width 539: "cell (M) should not have three vertical stripes along its right edge."
+      LayoutBlockFlow {P} at (0,661.20) size 769x45
+        LayoutText {#text} at (0,0) size 749x45
+          text run at (0,0) width 749: "In the second column, three vertical strips should run along the right of the first three cells,"
+          text run at (0,15) width 742: "aligning along cell F's right padding edge. (The stripes will be partially obscured by cell B's"
+          text run at (0,30) width 110: "thick border.)"
+      LayoutBlockFlow {P} at (0,719.20) size 769x45
+        LayoutText {#text} at (0,0) size 765x45
+          text run at (0,0) width 765: "In the third column, there should be three vertical stripes should run across the top of the first"
+          text run at (0,15) width 710: "cell and down the left of the column, aligning along cell K's left padding edge. In border-"
+          text run at (0,30) width 562: "collapse mode, they will be partially obscured by cell B's thick border."
+      LayoutBlockFlow {DIV} at (0,777.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,811.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
new file mode 100644
index 0000000..4285920
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-collapsed-border-expected.txt
new file mode 100644
index 0000000..0f9c47b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-collapsed-border-expected.txt
@@ -0,0 +1,80 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 654
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x654 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x654.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x631.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 466x17
+          text run at (0,0) width 466: "crbug.com/35679: Background on 'table-column-group'"
+      LayoutTable {TABLE} at (0,32.20) size 591x436 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 591x22
+          LayoutText {#text} at (151,0) size 289x22
+            text run at (151,0) width 289: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [border: (9px dashed #FFFFFF)]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,28) size 588x100
+          LayoutTableRow {TR} at (0,0) size 588x100
+            LayoutTableCell {TH} at (0,33) size 137x33 [border: (3px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (44,4) size 46x22
+                text run at (44,4) width 46: "TH A"
+            LayoutTableCell {TH} at (137,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (344,34) size 127x31 [border: (5px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,6) size 46x22
+                text run at (42,6) width 46: "TH C"
+            LayoutTableCell {TH} at (471,37) size 117x26 [border: (2px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (38,3) size 45x22
+                text run at (38,3) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,318) size 588x115
+          LayoutTableRow {TR} at (0,0) size 588x115
+            LayoutTableCell {TD} at (0,41) size 471x33 [border: (7px dashed #FFFFFF)] [r=0 c=0 rs=1 cs=3]
+              LayoutText {#text} at (4,8) size 47x22
+                text run at (4,8) width 47: "TD M"
+            LayoutTableCell {TD} at (471,44) size 117x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (6,2) size 44x22
+                text run at (6,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (1,128) size 588x190
+          LayoutTableRow {TR} at (0,0) size 588x107
+            LayoutTableCell {TD} at (0,76) size 137x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (137,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (344,39) size 127x29 [border: (3px dashed #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,4) size 46x22
+                text run at (6,4) width 46: "TD G"
+            LayoutTableCell {TD} at (471,41) size 117x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (6,2) size 45x22
+                text run at (6,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 588x83
+            LayoutTableCell {TD} at (137,135) size 207x27 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (344,134) size 127x29 [border: (3px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,4) size 45x22
+                text run at (6,4) width 45: "TD K"
+            LayoutTableCell {TD} at (471,136) size 117x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (6,2) size 43x22
+                text run at (6,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,481.20) size 769x45
+        LayoutText {#text} at (0,0) size 757x45
+          text run at (0,0) width 757: "Three aqua stripes should run along the bottom of the last cell in the first three columns and up"
+          text run at (0,15) width 757: "along the right edge of the cells in the third column. The stripes should align to be just inside"
+          text run at (0,30) width 266: "the padding edge in cells M and G."
+      LayoutBlockFlow {P} at (0,539.20) size 769x30
+        LayoutText {#text} at (0,0) size 757x30
+          text run at (0,0) width 757: "Three aqua stripes should also run just inside the top padding edge of the first cell in the last"
+          text run at (0,15) width 508: "column and down the left border edge of each cell in that column."
+      LayoutBlockFlow {DIV} at (0,582.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,616.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-expected.png
new file mode 100644
index 0000000..59a5db8e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-expected.txt
new file mode 100644
index 0000000..d0ca21f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-expected.txt
@@ -0,0 +1,83 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 688
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x688 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x688.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x665.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 466x17
+          text run at (0,0) width 466: "crbug.com/35679: Background on 'table-column-group'"
+      LayoutTable {TABLE} at (0,32.20) size 622x470 [color=#FFFFFF] [border: (3px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 622x22
+          LayoutText {#text} at (165,0) size 292x22
+            text run at (165,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [border: (9px dashed #FFFFFF)]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (3,25) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (3,345) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,40) size 357x34 [border: (5px dashed #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (6,6) size 47x22
+                text run at (6,6) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (3,139) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,37) size 118x34 [border: (5px dashed #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 46x22
+                text run at (6,6) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,515.20) size 769x45
+        LayoutText {#text} at (0,0) size 757x45
+          text run at (0,0) width 757: "Three aqua stripes should run along the bottom of the last cell in the first three columns and up"
+          text run at (0,15) width 757: "along the right edge of the cells in the third column. The stripes should align to be just inside"
+          text run at (0,30) width 266: "the padding edge in cells M and G."
+      LayoutBlockFlow {P} at (0,573.20) size 769x30
+        LayoutText {#text} at (0,0) size 757x30
+          text run at (0,0) width 757: "Three aqua stripes should also run just inside the top padding edge of the first cell in the last"
+          text run at (0,15) width 508: "column and down the left border edge of each cell in that column."
+      LayoutBlockFlow {DIV} at (0,616.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,650.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-expected.png
new file mode 100644
index 0000000..c39693a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-expected.txt
new file mode 100644
index 0000000..eca2953
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-expected.txt
@@ -0,0 +1,77 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 606
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x606 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x606.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x583.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 192x17
+          text run at (0,0) width 192: "Background on 'table'"
+      LayoutBlockFlow {P} at (0,32.20) size 769x15
+        LayoutText {#text} at (0,0) size 640x15
+          text run at (0,0) width 640: "There should be three aqua stripes just inside the bottom and right table borders."
+      LayoutTable {TABLE} at (0,60.20) size 626x474 [color=#FFFFFF] [bgcolor=#000000] [border: (5px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 626x22
+          LayoutText {#text} at (167,0) size 292x22
+            text run at (167,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (5,27) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TBODY} at (5,141) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+        LayoutTableSection {TFOOT} at (5,347) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+      LayoutBlockFlow {DIV} at (0,534.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,568.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
new file mode 100644
index 0000000..4d33c01
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-collapsed-border-expected.txt
new file mode 100644
index 0000000..3c7c02f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-collapsed-border-expected.txt
@@ -0,0 +1,77 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 784x17
+        LayoutText {#text} at (0,0) size 347x17
+          text run at (0,0) width 347: "crbug.com/35679: Background on 'table'"
+      LayoutBlockFlow {P} at (0,32.20) size 784x15
+        LayoutText {#text} at (0,0) size 640x15
+          text run at (0,0) width 640: "There should be three aqua stripes just inside the bottom and right table borders."
+      LayoutTable {TABLE} at (0,60.20) size 586x422 [color=#FFFFFF] [bgcolor=#000000] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 586x22
+          LayoutText {#text} at (148,0) size 290x22
+            text run at (148,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (2,28) size 581x96
+          LayoutTableRow {TR} at (0,0) size 581x96
+            LayoutTableCell {TH} at (0,31) size 137x33 [border: (3px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (44,4) size 46x22
+                text run at (44,4) width 46: "TH A"
+            LayoutTableCell {TH} at (137,29) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (344,34) size 123x27 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,4) size 46x22
+                text run at (42,4) width 46: "TH C"
+            LayoutTableCell {TH} at (467,34) size 114x27 [border: (3px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,4) size 45x22
+                text run at (34,4) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (2,308) size 581x111
+          LayoutTableRow {TR} at (0,0) size 581x111
+            LayoutTableCell {TD} at (0,39) size 344x33 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (4,8) size 47x22
+                text run at (4,8) width 47: "TD M"
+            LayoutTableCell {TD} at (344,42) size 123x27 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (467,42) size 114x27 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (2,124) size 581x184
+          LayoutTableRow {TR} at (0,0) size 581x104
+            LayoutTableCell {TD} at (0,73) size 137x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (137,36) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (344,39) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (467,39) size 114x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,104) size 581x80
+            LayoutTableCell {TD} at (137,131) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (344,131) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (467,131) size 114x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {DIV} at (0,482.20) size 784x31
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,513.20) size 784x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-expected.png
new file mode 100644
index 0000000..2880f09
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-expected.txt
new file mode 100644
index 0000000..489cd78
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-expected.txt
@@ -0,0 +1,77 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 784x17
+        LayoutText {#text} at (0,0) size 347x17
+          text run at (0,0) width 347: "crbug.com/35679: Background on 'table'"
+      LayoutBlockFlow {P} at (0,32.20) size 784x15
+        LayoutText {#text} at (0,0) size 640x15
+          text run at (0,0) width 640: "There should be three aqua stripes just inside the bottom and right table borders."
+      LayoutTable {TABLE} at (0,60.20) size 626x458 [color=#FFFFFF] [bgcolor=#000000] [border: (5px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 626x22
+          LayoutText {#text} at (167,0) size 292x22
+            text run at (167,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (5,27) size 616x110
+          LayoutTableRow {TR} at (0,7) size 616x96
+            LayoutTableCell {TH} at (7,42) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,30) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,42) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,42) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TBODY} at (5,137) size 616x198
+          LayoutTableRow {TR} at (0,0) size 616x104
+            LayoutTableCell {TD} at (7,70) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,39) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,39) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,39) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,111) size 616x80
+            LayoutTableCell {TD} at (144,138) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,138) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,138) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+        LayoutTableSection {TFOOT} at (5,335) size 616x118
+          LayoutTableRow {TR} at (0,0) size 616x111
+            LayoutTableCell {TD} at (7,42) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+      LayoutBlockFlow {DIV} at (0,518.20) size 784x31
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,549.20) size 784x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-collapsed-border-expected.png
new file mode 100644
index 0000000..ed07ff1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-collapsed-border-expected.txt
new file mode 100644
index 0000000..a622dbe
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-collapsed-border-expected.txt
@@ -0,0 +1,92 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 775
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x775 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x775.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x752.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 384x17
+          text run at (0,0) width 384: "crbug.com/35679: Background on 'table-row'"
+      LayoutTable {TABLE} at (0,32.20) size 590x456 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 590x22
+          LayoutText {#text} at (150,0) size 290x22
+            text run at (150,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (2,28) size 585x105
+          LayoutTableRow {TR} at (0,0) size 585x105 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+            LayoutTableCell {TH} at (0,36) size 137x33 [border: (3px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (44,4) size 46x22
+                text run at (44,4) width 46: "TH A"
+            LayoutTableCell {TH} at (137,34) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (344,37) size 125x31 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,4) size 46x22
+                text run at (42,4) width 46: "TH C"
+            LayoutTableCell {TH} at (469,37) size 116x31 [border: (3px dashed #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (36,4) size 45x22
+                text run at (36,4) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (2,337) size 585x117
+          LayoutTableRow {TR} at (0,0) size 585x117
+            LayoutTableCell {TD} at (0,42) size 344x32 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (3,8) size 47x22
+                text run at (3,8) width 47: "TD M"
+            LayoutTableCell {TD} at (344,44) size 125x28 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,4) size 46x22
+                text run at (2,4) width 46: "TD O"
+            LayoutTableCell {TD} at (469,44) size 116x28 [border: (3px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,4) size 44x22
+                text run at (2,4) width 44: "TD P"
+        LayoutTableSection {TBODY} at (2,133) size 585x204
+          LayoutTableRow {TR} at (0,0) size 585x115 [bgcolor=#000000] [border: (9px dashed #FFFFFF)]
+            LayoutTableCell {TD} at (0,83) size 137x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (137,40) size 207x35 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (344,41) size 125x33 [border: (5px dashed #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 46x22
+                text run at (6,6) width 46: "TD G"
+            LayoutTableCell {TD} at (469,41) size 116x33 [border: (5px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 45x22
+                text run at (6,6) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 585x89 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+            LayoutTableCell {TD} at (137,144) size 207x31 [border: (5px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,6) size 42x22
+                text run at (8,6) width 42: "TD J"
+            LayoutTableCell {TD} at (344,144) size 125x31 [border: (5px dashed #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (4,6) size 45x22
+                text run at (4,6) width 45: "TD K"
+            LayoutTableCell {TD} at (469,144) size 116x31 [border: (5px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (4,6) size 43x22
+                text run at (4,6) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,501.20) size 769x15
+        LayoutText {#text} at (0,0) size 172x15
+          text run at (0,0) width 172: "Three rows are styled."
+      LayoutBlockFlow {P} at (0,529.20) size 769x60
+        LayoutText {#text} at (0,0) size 765x60
+          text run at (0,0) width 765: "The first row should have three aqua stripes just inside the bottom and right padding edges of its"
+          text run at (0,15) width 757: "last cell. The bottom three stripes should continue across the row, appearing along the bottom of"
+          text run at (0,30) width 749: "cells A, B, and C. (The bottom aqua stripe will be obscured by the thicker bottom border in cell"
+          text run at (0,45) width 24: "B.)"
+      LayoutBlockFlow {P} at (0,602.20) size 769x45
+        LayoutText {#text} at (0,0) size 749x45
+          text run at (0,0) width 718: "The second row should have three vertical aqua stripes a few pixels to the right of the left"
+          text run at (0,15) width 749: "padding edge. Three horizontal aqua stripes should cut across the first cell and align along the"
+          text run at (0,30) width 227: "bottom border edge of cell G."
+      LayoutBlockFlow {P} at (0,660.20) size 769x30
+        LayoutText {#text} at (0,0) size 734x30
+          text run at (0,0) width 734: "The third row should have three horizontal aqua stripes along the top of the last three cells,"
+          text run at (0,15) width 656: "aligning along cell K's top padding edge. The stripes will not continue into cell E."
+      LayoutBlockFlow {DIV} at (0,703.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,737.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-expected.png
new file mode 100644
index 0000000..620b0cf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-expected.txt
new file mode 100644
index 0000000..2df8a9e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-expected.txt
@@ -0,0 +1,92 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 797
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x797 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x797.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x774.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 384x17
+          text run at (0,0) width 384: "crbug.com/35679: Background on 'table-row'"
+      LayoutTable {TABLE} at (0,32.20) size 630x478 [color=#FFFFFF] [border: (3px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 630x22
+          LayoutText {#text} at (169,0) size 292x22
+            text run at (169,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (3,25) size 624x122
+          LayoutTableRow {TR} at (0,7) size 624x108 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+            LayoutTableCell {TH} at (7,48) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,36) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,48) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 121x34 [border: (5px dashed #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (38,6) size 45x22
+                text run at (38,6) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (3,353) size 624x122
+          LayoutTableRow {TR} at (0,0) size 624x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 121x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (3,147) size 624x206
+          LayoutTableRow {TR} at (0,0) size 624x108 [bgcolor=#000000] [border: (9px dashed #FFFFFF)]
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,33) size 118x42 [border: (9px dashed #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (10,10) size 46x22
+                text run at (10,10) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 121x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 624x84 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,140) size 118x34 [border: (5px dashed #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 45x22
+                text run at (6,6) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 121x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,523.20) size 769x15
+        LayoutText {#text} at (0,0) size 172x15
+          text run at (0,0) width 172: "Three rows are styled."
+      LayoutBlockFlow {P} at (0,551.20) size 769x60
+        LayoutText {#text} at (0,0) size 765x60
+          text run at (0,0) width 765: "The first row should have three aqua stripes just inside the bottom and right padding edges of its"
+          text run at (0,15) width 757: "last cell. The bottom three stripes should continue across the row, appearing along the bottom of"
+          text run at (0,30) width 749: "cells A, B, and C. (The bottom aqua stripe will be obscured by the thicker bottom border in cell"
+          text run at (0,45) width 24: "B.)"
+      LayoutBlockFlow {P} at (0,624.20) size 769x45
+        LayoutText {#text} at (0,0) size 749x45
+          text run at (0,0) width 718: "The second row should have three vertical aqua stripes a few pixels to the right of the left"
+          text run at (0,15) width 749: "padding edge. Three horizontal aqua stripes should cut across the first cell and align along the"
+          text run at (0,30) width 227: "bottom border edge of cell G."
+      LayoutBlockFlow {P} at (0,682.20) size 769x30
+        LayoutText {#text} at (0,0) size 734x30
+          text run at (0,0) width 734: "The third row should have three horizontal aqua stripes along the top of the last three cells,"
+          text run at (0,15) width 656: "aligning along cell K's top padding edge. The stripes will not continue into cell E."
+      LayoutBlockFlow {DIV} at (0,725.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,759.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
new file mode 100644
index 0000000..8a2cdd5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-collapsed-border-expected.txt
new file mode 100644
index 0000000..e6112f6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-collapsed-border-expected.txt
@@ -0,0 +1,85 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 692
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x692 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x692.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x669.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 439x17
+          text run at (0,0) width 439: "crbug.com/35679: Background on 'table-row-group'"
+      LayoutTable {TABLE} at (0,32.20) size 590x444 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 590x22
+          LayoutText {#text} at (150,0) size 290x22
+            text run at (150,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (2,28) size 585x103 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableRow {TR} at (0,0) size 585x103
+            LayoutTableCell {TH} at (0,35) size 137x33 [border: (3px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (44,4) size 46x22
+                text run at (44,4) width 46: "TH A"
+            LayoutTableCell {TH} at (137,33) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (344,37) size 125x29 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,4) size 46x22
+                text run at (42,4) width 46: "TH C"
+            LayoutTableCell {TH} at (469,37) size 116x29 [border: (3px dashed #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (36,4) size 45x22
+                text run at (36,4) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (2,325) size 585x117
+          LayoutTableRow {TR} at (0,0) size 585x117
+            LayoutTableCell {TD} at (0,42) size 344x32 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (3,8) size 47x22
+                text run at (3,8) width 47: "TD M"
+            LayoutTableCell {TD} at (344,44) size 125x28 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,4) size 46x22
+                text run at (2,4) width 46: "TD O"
+            LayoutTableCell {TD} at (469,44) size 116x28 [border: (3px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,4) size 44x22
+                text run at (2,4) width 44: "TD P"
+        LayoutTableSection {TBODY} at (2,131) size 585x194 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableRow {TR} at (0,0) size 585x109
+            LayoutTableCell {TD} at (0,78) size 137x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (137,39) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (344,40) size 125x29 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,4) size 46x22
+                text run at (2,4) width 46: "TD G"
+            LayoutTableCell {TD} at (469,41) size 116x27 [border: (3px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,4) size 45x22
+                text run at (2,4) width 45: "TD H"
+          LayoutTableRow {TR} at (0,109) size 585x85
+            LayoutTableCell {TD} at (137,138) size 207x27 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (344,137) size 125x29 [border: (3px dashed #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (4,4) size 45x22
+                text run at (4,4) width 45: "TD K"
+            LayoutTableCell {TD} at (469,138) size 116x27 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (4,2) size 43x22
+                text run at (4,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,489.20) size 769x45
+        LayoutText {#text} at (0,0) size 765x45
+          text run at (0,0) width 726: "There should be three aqua stripes along the top of cells A, B, C, and D in the first row and"
+          text run at (0,15) width 765: "three stripes along the right edge of D, the last cell in that row. The stripes should align to be"
+          text run at (0,30) width 305: "just inside the padding edge of cell D."
+      LayoutBlockFlow {P} at (0,547.20) size 769x60
+        LayoutText {#text} at (0,0) size 765x60
+          text run at (0,0) width 734: "There should be three aqua stripes along the bottom of cells J, K, and L. The stripes continue"
+          text run at (0,15) width 765: "across the bottom of cell E, but are partially obscured by the border. The stripes turn up at cell"
+          text run at (0,30) width 757: "E's bottom left corner to run under its border a few pixels to the right of its left border edge."
+          text run at (0,45) width 539: "The stripes will align to be just above cell K's bottom padding edge."
+      LayoutBlockFlow {DIV} at (0,620.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,654.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-expected.png
new file mode 100644
index 0000000..1b9db53
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-expected.txt
new file mode 100644
index 0000000..2b92942
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-expected.txt
@@ -0,0 +1,85 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 726
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x726 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x726.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x703.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 439x17
+          text run at (0,0) width 439: "crbug.com/35679: Background on 'table-row-group'"
+      LayoutTable {TABLE} at (0,32.20) size 630x478 [color=#FFFFFF] [border: (3px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 630x22
+          LayoutText {#text} at (169,0) size 292x22
+            text run at (169,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (3,25) size 624x122 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableRow {TR} at (0,7) size 624x108
+            LayoutTableCell {TH} at (7,48) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,36) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,48) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 121x34 [border: (5px dashed #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (38,6) size 45x22
+                text run at (38,6) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (3,353) size 624x122
+          LayoutTableRow {TR} at (0,0) size 624x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 121x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (3,147) size 624x206 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableRow {TR} at (0,0) size 624x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 121x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 624x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,140) size 118x34 [border: (5px dashed #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 45x22
+                text run at (6,6) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 121x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,523.20) size 769x45
+        LayoutText {#text} at (0,0) size 765x45
+          text run at (0,0) width 726: "There should be three aqua stripes along the top of cells A, B, C, and D in the first row and"
+          text run at (0,15) width 765: "three stripes along the right edge of D, the last cell in that row. The stripes should align to be"
+          text run at (0,30) width 305: "just inside the padding edge of cell D."
+      LayoutBlockFlow {P} at (0,581.20) size 769x60
+        LayoutText {#text} at (0,0) size 765x60
+          text run at (0,0) width 734: "There should be three aqua stripes along the bottom of cells J, K, and L. The stripes continue"
+          text run at (0,15) width 765: "across the bottom of cell E, but are partially obscured by the border. The stripes turn up at cell"
+          text run at (0,30) width 757: "E's bottom left corner to run under its border a few pixels to the right of its left border edge."
+          text run at (0,45) width 539: "The stripes will align to be just above cell K's bottom padding edge."
+      LayoutBlockFlow {DIV} at (0,654.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,688.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-collapsed-border-expected.png
new file mode 100644
index 0000000..64a186f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-collapsed-border-expected.txt
new file mode 100644
index 0000000..942d380
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-collapsed-border-expected.txt
@@ -0,0 +1,81 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x592
+  LayoutBlockFlow {HTML} at (0,0) size 800x592.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 784x569.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 784x17
+        LayoutText {#text} at (0,0) size 311x17
+          text run at (0,0) width 311: "crbug.com/35679: empty-cells: hide"
+      LayoutTable {TABLE} at (0,32.20) size 578x432 [color=#FFFFFF] [bgcolor=#0000FF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x22
+          LayoutText {#text} at (144,0) size 290x22
+            text run at (144,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,28) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,48) size 123x3 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,317) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,41) size 342x31 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 47x22
+                text run at (2,8) width 47: "TD M"
+            LayoutTableCell {TD} at (342,44) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (465,44) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (0,127) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,76) size 135x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (135,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (342,41) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (465,41) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,136) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (342,136) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (465,136) size 112x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,477.20) size 784x30
+        LayoutText {#text} at (0,0) size 383x15
+          text run at (0,0) width 383: "Both tables should look identical to the ones in "
+        LayoutInline {A} at (0,0) size 133x15 [color=#FFFF00]
+          LayoutText {#text} at (382,0) size 133x15
+            text run at (382,0) width 133: "empty-cells: show"
+        LayoutText {#text} at (514,0) size 749x30
+          text run at (514,0) width 235: " except that there should be a"
+          text run at (0,15) width 313: "blue blank where table cell C should be."
+      LayoutBlockFlow {DIV} at (0,520.20) size 784x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,554.20) size 784x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-expected.png
new file mode 100644
index 0000000..2b8e2b3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-expected.txt
new file mode 100644
index 0000000..86a62af
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-expected.txt
@@ -0,0 +1,81 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 626
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x626 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x626.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x603.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 311x17
+          text run at (0,0) width 311: "crbug.com/35679: empty-cells: hide"
+      LayoutTable {TABLE} at (0,32.20) size 618x466 [color=#FFFFFF] [bgcolor=#0000FF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x22
+          LayoutText {#text} at (163,0) size 292x22
+            text run at (163,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,23) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,55) size 118x4 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,343) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (1,137) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,511.20) size 769x30
+        LayoutText {#text} at (0,0) size 383x15
+          text run at (0,0) width 383: "Both tables should look identical to the ones in "
+        LayoutInline {A} at (0,0) size 133x15 [color=#FFFF00]
+          LayoutText {#text} at (382,0) size 133x15
+            text run at (382,0) width 133: "empty-cells: show"
+        LayoutText {#text} at (514,0) size 749x30
+          text run at (514,0) width 235: " except that there should be a"
+          text run at (0,15) width 313: "blue blank where table cell C should be."
+      LayoutBlockFlow {DIV} at (0,554.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,588.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-opacity-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-opacity-collapsed-border-expected.png
new file mode 100644
index 0000000..773131a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-opacity-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-opacity-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-opacity-collapsed-border-expected.txt
new file mode 100644
index 0000000..49b39cc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-opacity-collapsed-border-expected.txt
@@ -0,0 +1,103 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x350
+  LayoutBlockFlow {HTML} at (0,0) size 800x350.44
+    LayoutBlockFlow {BODY} at (8,18.72) size 784x323.72
+      LayoutBlockFlow {H3} at (0,0) size 784x22
+        LayoutText {#text} at (0,0) size 241x22
+          text run at (0,0) width 241: "crbug.com/35679: opacity: 0.5"
+      LayoutTable {TABLE} at (0,40.72) size 171x126 [bgcolor=#FFFFFF]
+        LayoutBlockFlow {CAPTION} at (0,0) size 171x36 [color=#FFFFFF]
+          LayoutText {#text} at (14,0) size 143x36
+            text run at (14,0) width 143: "With 'border-collapse:"
+            text run at (57,18) width 57: "collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,36) size 171x24
+        LayoutTableSection {TBODY} at (0,60) size 171x44
+      LayoutBlockFlow {UL} at (0,182.72) size 784x72
+        LayoutListItem {LI} at (40,0) size 744x18
+          LayoutListMarker (anonymous) at (-17,0) size 7x18: bullet
+          LayoutText {#text} at (0,0) size 220x18
+            text run at (0,0) width 220: "The first three rows should be red."
+        LayoutListItem {LI} at (40,18) size 744x18
+          LayoutListMarker (anonymous) at (-17,0) size 7x18: bullet
+          LayoutText {#text} at (0,0) size 198x18
+            text run at (0,0) width 198: "The last row should be orange."
+        LayoutListItem {LI} at (40,36) size 744x36
+          LayoutListMarker (anonymous) at (-17,0) size 7x18: bullet
+          LayoutText {#text} at (0,0) size 734x36
+            text run at (0,0) width 734: "Cell A should be purple. Cell P should also be purple, but of a shade that reflects the underlying orange rather than"
+            text run at (0,18) width 48: "the red."
+      LayoutBlockFlow {DIV} at (0,270.72) size 784x35
+        LayoutInline {A} at (0,0) size 88x18 [color=#0000EE]
+          LayoutBlockFlow {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,305.72) size 784x18
+        LayoutText {#text} at (0,0) size 606x18
+          text run at (0,0) width 606: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
+layer at (8,289) size 88x31 clip at (9,290) size 86x29 scrollHeight 56
+  LayoutBlockFlow {DIV} at (0,0) size 88x31 [border: (1px solid #C0C0C0)]
+    LayoutImage (floating) {IMG} at (2,2) size 16x16
+layer at (26,291) size 68x54 backgroundClip at (26,291) size 68x28 clip at (26,291) size 68x28
+  LayoutBlockFlow {DIV} at (18,2) size 68x54
+    LayoutText {#text} at (0,0) size 46x54
+      text run at (0,0) width 34: "Valid"
+      text run at (0,18) width 46: "HTML"
+      text run at (0,36) width 34: "4.01!"
+layer at (8,97) size 171x20 transparent
+  LayoutTableRow {TR} at (0,2) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TH} at (45,2) size 40x20 [r=0 c=1 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 38x18
+        text run at (1,1) width 38: "TH B"
+    LayoutTableCell {TH} at (87,11) size 39x2 [r=0 c=2 rs=1 cs=1]
+    LayoutTableCell {TH} at (128,2) size 41x20 [r=0 c=3 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 39x18
+        text run at (1,1) width 39: "TH D"
+layer at (10,97) size 41x20 transparent
+  LayoutTableCell {TH} at (2,2) size 41x20 [bgcolor=#0000FF] [r=0 c=0 rs=1 cs=1]
+    LayoutText {#text} at (1,1) size 39x18
+      text run at (1,1) width 39: "TH A"
+layer at (8,163) size 171x22 transparent
+  LayoutTableSection {TFOOT} at (0,104) size 171x22 [bgcolor=#FFFF00]
+layer at (8,163) size 171x20 transparent
+  LayoutTableRow {TR} at (0,0) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TD} at (2,0) size 83x20 [r=0 c=0 rs=1 cs=2]
+      LayoutText {#text} at (1,1) size 40x18
+        text run at (1,1) width 40: "TD M"
+    LayoutTableCell {TD} at (87,0) size 39x20 [r=0 c=2 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x18
+        text run at (1,1) width 37: "TD O"
+layer at (136,163) size 41x20 transparent
+  LayoutTableCell {TD} at (128,0) size 41x20 [bgcolor=#0000FF] [r=0 c=3 rs=1 cs=1]
+    LayoutText {#text} at (1,1) size 35x18
+      text run at (1,1) width 35: "TD P"
+layer at (8,119) size 171x20 transparent
+  LayoutTableRow {TR} at (0,0) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TD} at (2,11) size 41x20 [r=0 c=0 rs=2 cs=1]
+      LayoutText {#text} at (1,1) size 36x18
+        text run at (1,1) width 36: "TD E"
+    LayoutTableCell {TD} at (45,0) size 40x20 [r=0 c=1 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 35x18
+        text run at (1,1) width 35: "TD F"
+    LayoutTableCell {TD} at (87,0) size 39x20 [r=0 c=2 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x18
+        text run at (1,1) width 37: "TD G"
+    LayoutTableCell {TD} at (128,0) size 41x20 [r=0 c=3 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x18
+        text run at (1,1) width 37: "TD H"
+layer at (8,141) size 171x20 transparent
+  LayoutTableRow {TR} at (0,22) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TD} at (45,22) size 40x20 [r=1 c=1 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 32x18
+        text run at (1,1) width 32: "TD J"
+    LayoutTableCell {TD} at (87,22) size 39x20 [r=1 c=2 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x18
+        text run at (1,1) width 37: "TD K"
+    LayoutTableCell {TD} at (128,22) size 41x20 [r=1 c=3 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 36x18
+        text run at (1,1) width 36: "TD L"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-opacity-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-opacity-expected.png
new file mode 100644
index 0000000..773131a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-opacity-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-opacity-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-opacity-expected.txt
new file mode 100644
index 0000000..da4043a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-opacity-expected.txt
@@ -0,0 +1,103 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x350
+  LayoutBlockFlow {HTML} at (0,0) size 800x350.44
+    LayoutBlockFlow {BODY} at (8,18.72) size 784x323.72
+      LayoutBlockFlow {H3} at (0,0) size 784x22
+        LayoutText {#text} at (0,0) size 241x22
+          text run at (0,0) width 241: "crbug.com/35679: opacity: 0.5"
+      LayoutTable {TABLE} at (0,40.72) size 171x126 [bgcolor=#FFFFFF]
+        LayoutBlockFlow {CAPTION} at (0,0) size 171x36 [color=#FFFFFF]
+          LayoutText {#text} at (14,0) size 143x36
+            text run at (14,0) width 143: "With 'border-collapse:"
+            text run at (57,18) width 57: "separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,36) size 171x24
+        LayoutTableSection {TBODY} at (0,60) size 171x44
+      LayoutBlockFlow {UL} at (0,182.72) size 784x72
+        LayoutListItem {LI} at (40,0) size 744x18
+          LayoutListMarker (anonymous) at (-17,0) size 7x18: bullet
+          LayoutText {#text} at (0,0) size 220x18
+            text run at (0,0) width 220: "The first three rows should be red."
+        LayoutListItem {LI} at (40,18) size 744x18
+          LayoutListMarker (anonymous) at (-17,0) size 7x18: bullet
+          LayoutText {#text} at (0,0) size 198x18
+            text run at (0,0) width 198: "The last row should be orange."
+        LayoutListItem {LI} at (40,36) size 744x36
+          LayoutListMarker (anonymous) at (-17,0) size 7x18: bullet
+          LayoutText {#text} at (0,0) size 734x36
+            text run at (0,0) width 734: "Cell A should be purple. Cell P should also be purple, but of a shade that reflects the underlying orange rather than"
+            text run at (0,18) width 48: "the red."
+      LayoutBlockFlow {DIV} at (0,270.72) size 784x35
+        LayoutInline {A} at (0,0) size 88x18 [color=#0000EE]
+          LayoutBlockFlow {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,305.72) size 784x18
+        LayoutText {#text} at (0,0) size 606x18
+          text run at (0,0) width 606: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
+layer at (8,289) size 88x31 clip at (9,290) size 86x29 scrollHeight 56
+  LayoutBlockFlow {DIV} at (0,0) size 88x31 [border: (1px solid #C0C0C0)]
+    LayoutImage (floating) {IMG} at (2,2) size 16x16
+layer at (26,291) size 68x54 backgroundClip at (26,291) size 68x28 clip at (26,291) size 68x28
+  LayoutBlockFlow {DIV} at (18,2) size 68x54
+    LayoutText {#text} at (0,0) size 46x54
+      text run at (0,0) width 34: "Valid"
+      text run at (0,18) width 46: "HTML"
+      text run at (0,36) width 34: "4.01!"
+layer at (8,97) size 171x20 transparent
+  LayoutTableRow {TR} at (0,2) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TH} at (45,2) size 40x20 [r=0 c=1 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 38x18
+        text run at (1,1) width 38: "TH B"
+    LayoutTableCell {TH} at (87,11) size 39x2 [r=0 c=2 rs=1 cs=1]
+    LayoutTableCell {TH} at (128,2) size 41x20 [r=0 c=3 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 39x18
+        text run at (1,1) width 39: "TH D"
+layer at (10,97) size 41x20 transparent
+  LayoutTableCell {TH} at (2,2) size 41x20 [bgcolor=#0000FF] [r=0 c=0 rs=1 cs=1]
+    LayoutText {#text} at (1,1) size 39x18
+      text run at (1,1) width 39: "TH A"
+layer at (8,163) size 171x22 transparent
+  LayoutTableSection {TFOOT} at (0,104) size 171x22 [bgcolor=#FFFF00]
+layer at (8,163) size 171x20 transparent
+  LayoutTableRow {TR} at (0,0) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TD} at (2,0) size 83x20 [r=0 c=0 rs=1 cs=2]
+      LayoutText {#text} at (1,1) size 40x18
+        text run at (1,1) width 40: "TD M"
+    LayoutTableCell {TD} at (87,0) size 39x20 [r=0 c=2 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x18
+        text run at (1,1) width 37: "TD O"
+layer at (136,163) size 41x20 transparent
+  LayoutTableCell {TD} at (128,0) size 41x20 [bgcolor=#0000FF] [r=0 c=3 rs=1 cs=1]
+    LayoutText {#text} at (1,1) size 35x18
+      text run at (1,1) width 35: "TD P"
+layer at (8,119) size 171x20 transparent
+  LayoutTableRow {TR} at (0,0) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TD} at (2,11) size 41x20 [r=0 c=0 rs=2 cs=1]
+      LayoutText {#text} at (1,1) size 36x18
+        text run at (1,1) width 36: "TD E"
+    LayoutTableCell {TD} at (45,0) size 40x20 [r=0 c=1 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 35x18
+        text run at (1,1) width 35: "TD F"
+    LayoutTableCell {TD} at (87,0) size 39x20 [r=0 c=2 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x18
+        text run at (1,1) width 37: "TD G"
+    LayoutTableCell {TD} at (128,0) size 41x20 [r=0 c=3 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x18
+        text run at (1,1) width 37: "TD H"
+layer at (8,141) size 171x20 transparent
+  LayoutTableRow {TR} at (0,22) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TD} at (45,22) size 40x20 [r=1 c=1 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 32x18
+        text run at (1,1) width 32: "TD J"
+    LayoutTableCell {TD} at (87,22) size 39x20 [r=1 c=2 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x18
+        text run at (1,1) width 37: "TD K"
+    LayoutTableCell {TD} at (128,22) size 41x20 [r=1 c=3 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 36x18
+        text run at (1,1) width 36: "TD L"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-show-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-show-collapsed-border-expected.png
new file mode 100644
index 0000000..4fa6b1b2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-show-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-show-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-show-expected.png
new file mode 100644
index 0000000..c759170
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-show-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-collapsed-border-expected.png
new file mode 100644
index 0000000..abe4753
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-collapsed-border-expected.txt
new file mode 100644
index 0000000..dae722a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-collapsed-border-expected.txt
@@ -0,0 +1,83 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 633
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x633 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x633.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x610.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 393x17
+          text run at (0,0) width 393: "crbug.com/35679: Background on 'table-cell'"
+      LayoutTable {TABLE} at (0,32.20) size 578x432 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x22
+          LayoutText {#text} at (144,0) size 290x22
+            text run at (144,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,28) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,317) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,41) size 342x31 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 47x22
+                text run at (2,8) width 47: "TD M"
+            LayoutTableCell {TD} at (342,44) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (465,44) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (0,127) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,76) size 135x37 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (135,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (342,41) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (465,41) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,136) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (342,136) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (465,136) size 112x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,477.20) size 769x15
+        LayoutText {#text} at (0,0) size 164x15
+          text run at (0,0) width 164: "Two cells are styled."
+      LayoutBlockFlow {P} at (0,505.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "There should be three aqua stripes just inside the top and left padding edges of cell E."
+      LayoutBlockFlow {P} at (0,533.20) size 769x15
+        LayoutText {#text} at (0,0) size 710x15
+          text run at (0,0) width 710: "There should be three aqua stripes just inside the bottom and right padding edges of Cell M"
+      LayoutBlockFlow {DIV} at (0,561.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,595.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-expected.png
new file mode 100644
index 0000000..cd87e477
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-expected.txt
new file mode 100644
index 0000000..8b46d616
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-expected.txt
@@ -0,0 +1,83 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 667
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x667 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x667.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x644.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 393x17
+          text run at (0,0) width 393: "crbug.com/35679: Background on 'table-cell'"
+      LayoutTable {TABLE} at (0,32.20) size 618x466 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x22
+          LayoutText {#text} at (163,0) size 292x22
+            text run at (163,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,23) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,343) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (1,137) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [bgcolor=#000000] [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,511.20) size 769x15
+        LayoutText {#text} at (0,0) size 164x15
+          text run at (0,0) width 164: "Two cells are styled."
+      LayoutBlockFlow {P} at (0,539.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "There should be three aqua stripes just inside the top and left padding edges of cell E."
+      LayoutBlockFlow {P} at (0,567.20) size 769x15
+        LayoutText {#text} at (0,0) size 710x15
+          text run at (0,0) width 710: "There should be three aqua stripes just inside the bottom and right padding edges of Cell M"
+      LayoutBlockFlow {DIV} at (0,595.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,629.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-collapsed-border-expected.png
new file mode 100644
index 0000000..a882d703
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-collapsed-border-expected.txt
new file mode 100644
index 0000000..285ec49
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-collapsed-border-expected.txt
@@ -0,0 +1,77 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x564
+  LayoutBlockFlow {HTML} at (0,0) size 800x564.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 784x541.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 784x17
+        LayoutText {#text} at (0,0) size 347x17
+          text run at (0,0) width 347: "crbug.com/35679: Background on 'table'"
+      LayoutBlockFlow {P} at (0,32.20) size 784x15
+        LayoutText {#text} at (0,0) size 617x15
+          text run at (0,0) width 617: "There should be three aqua stripes just inside the top and right table borders."
+      LayoutTable {TABLE} at (0,60.20) size 578x432 [color=#FFFFFF] [bgcolor=#000000] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x22
+          LayoutText {#text} at (144,0) size 290x22
+            text run at (144,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,28) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,317) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,41) size 342x31 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 47x22
+                text run at (2,8) width 47: "TD M"
+            LayoutTableCell {TD} at (342,44) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (465,44) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (0,127) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,76) size 135x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (135,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (342,41) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (465,41) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,136) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (342,136) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (465,136) size 112x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {DIV} at (0,492.20) size 784x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,526.20) size 784x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-collapsed-border-expected.png
new file mode 100644
index 0000000..f64d8ea
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-collapsed-border-expected.txt
new file mode 100644
index 0000000..56b4df1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-collapsed-border-expected.txt
@@ -0,0 +1,87 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 693
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x693 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x693.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x670.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 411x17
+          text run at (0,0) width 411: "crbug.com/35679: Background on 'table-column'"
+      LayoutTable {TABLE} at (0,32.20) size 578x432 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x22
+          LayoutText {#text} at (144,0) size 290x22
+            text run at (144,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,28) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,317) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,41) size 342x31 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 47x22
+                text run at (2,8) width 47: "TD M"
+            LayoutTableCell {TD} at (342,44) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (465,44) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (0,127) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,76) size 135x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (135,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (342,41) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (465,41) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,136) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (342,136) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (465,136) size 112x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,477.20) size 769x15
+        LayoutText {#text} at (0,0) size 196x15
+          text run at (0,0) width 196: "Three columns are styled."
+      LayoutBlockFlow {P} at (0,505.20) size 769x60
+        LayoutText {#text} at (0,0) size 757x60
+          text run at (0,0) width 749: "In the first column, there should be three vertical stripes just inside the right border edge of"
+          text run at (0,15) width 757: "the first three cells. The stripes should continue in the last cell, turning a right angle to the"
+          text run at (0,30) width 749: "left into three aqua stripes along the bottom border edge of the last cell. The last cell should"
+          text run at (0,45) width 469: "not have three vertical stripes along its right border edge."
+      LayoutBlockFlow {P} at (0,578.20) size 769x30
+        LayoutText {#text} at (0,0) size 757x30
+          text run at (0,0) width 757: "In the second column, there should be three vertical stripes just inside the right border edge of"
+          text run at (0,15) width 172: "the first three cells."
+      LayoutBlockFlow {DIV} at (0,621.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,655.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-expected.png
new file mode 100644
index 0000000..2c543f9f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-expected.txt
new file mode 100644
index 0000000..2f6e677
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-expected.txt
@@ -0,0 +1,91 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 770
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x770 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x770.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x747.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 411x17
+          text run at (0,0) width 411: "crbug.com/35679: Background on 'table-column'"
+      LayoutTable {TABLE} at (0,32.20) size 618x466 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x22
+          LayoutText {#text} at (163,0) size 292x22
+            text run at (163,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,23) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,343) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (1,137) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,511.20) size 769x15
+        LayoutText {#text} at (0,0) size 196x15
+          text run at (0,0) width 196: "Three columns are styled."
+      LayoutBlockFlow {P} at (0,539.20) size 769x60
+        LayoutText {#text} at (0,0) size 757x60
+          text run at (0,0) width 749: "In the first column, there should be three vertical stripes just inside the right border edge of"
+          text run at (0,15) width 757: "the first three cells. The stripes should continue in the last cell, turning a right angle to the"
+          text run at (0,30) width 749: "left into three aqua stripes along the bottom border edge of the last cell. The last cell should"
+          text run at (0,45) width 469: "not have three vertical stripes along its right border edge."
+      LayoutBlockFlow {P} at (0,612.20) size 769x30
+        LayoutText {#text} at (0,0) size 757x30
+          text run at (0,0) width 757: "In the second column, there should be three vertical stripes just inside the right border edge of"
+          text run at (0,15) width 172: "the first three cells."
+      LayoutBlockFlow {P} at (0,655.20) size 769x30
+        LayoutText {#text} at (0,0) size 765x30
+          text run at (0,0) width 765: "In the third column, there should be three vertical stripes just inside the top border edge of the"
+          text run at (0,15) width 461: "first cell and just inside the left edge of all four cells."
+      LayoutBlockFlow {DIV} at (0,698.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,732.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
new file mode 100644
index 0000000..95aeea4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-collapsed-border-expected.txt
new file mode 100644
index 0000000..0ebc886
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-collapsed-border-expected.txt
@@ -0,0 +1,79 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 635
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x635 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x635.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x612.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 466x17
+          text run at (0,0) width 466: "crbug.com/35679: Background on 'table-column-group'"
+      LayoutTable {TABLE} at (0,32.20) size 578x432 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x22
+          LayoutText {#text} at (144,0) size 290x22
+            text run at (144,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,28) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,317) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,41) size 465x31 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=3]
+              LayoutText {#text} at (2,8) size 47x22
+                text run at (2,8) width 47: "TD M"
+            LayoutTableCell {TD} at (465,44) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (0,127) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,76) size 135x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (135,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (342,41) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (465,41) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,136) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (342,136) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (465,136) size 112x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,477.20) size 769x30
+        LayoutText {#text} at (0,0) size 734x30
+          text run at (0,0) width 734: "Three aqua stripes should run just inside the bottom border edge of the last cell in the first"
+          text run at (0,15) width 593: "three columns and up the right border edge of the cells in the third column."
+      LayoutBlockFlow {P} at (0,520.20) size 769x30
+        LayoutText {#text} at (0,0) size 749x30
+          text run at (0,0) width 749: "Three aqua stripes should also run just inside the top border edge of the first cell in the last"
+          text run at (0,15) width 508: "column and down the left border edge of each cell in that column."
+      LayoutBlockFlow {DIV} at (0,563.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,597.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-expected.png
new file mode 100644
index 0000000..ef1502c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-expected.txt
new file mode 100644
index 0000000..86a9e99
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-expected.txt
@@ -0,0 +1,82 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 669
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x669 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x669.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x646.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 466x17
+          text run at (0,0) width 466: "crbug.com/35679: Background on 'table-column-group'"
+      LayoutTable {TABLE} at (0,32.20) size 618x466 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x22
+          LayoutText {#text} at (163,0) size 292x22
+            text run at (163,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,23) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,343) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (1,137) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,511.20) size 769x30
+        LayoutText {#text} at (0,0) size 734x30
+          text run at (0,0) width 734: "Three aqua stripes should run just inside the bottom border edge of the last cell in the first"
+          text run at (0,15) width 593: "three columns and up the right border edge of the cells in the third column."
+      LayoutBlockFlow {P} at (0,554.20) size 769x30
+        LayoutText {#text} at (0,0) size 749x30
+          text run at (0,0) width 749: "Three aqua stripes should also run just inside the top border edge of the first cell in the last"
+          text run at (0,15) width 508: "column and down the left border edge of each cell in that column."
+      LayoutBlockFlow {DIV} at (0,597.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,631.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-expected.png
new file mode 100644
index 0000000..79e773e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-expected.txt
new file mode 100644
index 0000000..89092ba2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-expected.txt
@@ -0,0 +1,77 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x598
+  LayoutBlockFlow {HTML} at (0,0) size 800x598.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 784x575.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 784x17
+        LayoutText {#text} at (0,0) size 347x17
+          text run at (0,0) width 347: "crbug.com/35679: Background on 'table'"
+      LayoutBlockFlow {P} at (0,32.20) size 784x15
+        LayoutText {#text} at (0,0) size 617x15
+          text run at (0,0) width 617: "There should be three aqua stripes just inside the top and right table borders."
+      LayoutTable {TABLE} at (0,60.20) size 618x466 [color=#FFFFFF] [bgcolor=#000000] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x22
+          LayoutText {#text} at (163,0) size 292x22
+            text run at (163,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,23) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TBODY} at (1,137) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+        LayoutTableSection {TFOOT} at (1,343) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+      LayoutBlockFlow {DIV} at (0,526.20) size 784x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,560.20) size 784x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-collapsed-border-expected.png
new file mode 100644
index 0000000..fe96405
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-collapsed-border-expected.txt
new file mode 100644
index 0000000..0b42183c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-collapsed-border-expected.txt
@@ -0,0 +1,96 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 736
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x736 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x736.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x713.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 384x17
+          text run at (0,0) width 384: "crbug.com/35679: Background on 'table-row'"
+      LayoutTable {TABLE} at (0,32.20) size 578x432 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x22
+          LayoutText {#text} at (144,0) size 290x22
+            text run at (144,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,28) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99 [bgcolor=#000000]
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,317) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,41) size 342x31 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 47x22
+                text run at (2,8) width 47: "TD M"
+            LayoutTableCell {TD} at (342,44) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (465,44) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (0,127) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107 [bgcolor=#000000]
+            LayoutTableCell {TD} at (0,76) size 135x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (135,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (342,41) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (465,41) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83 [bgcolor=#000000]
+            LayoutTableCell {TD} at (135,136) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (342,136) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (465,136) size 112x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,477.20) size 769x15
+        LayoutText {#text} at (0,0) size 172x15
+          text run at (0,0) width 172: "Three rows are styled."
+      LayoutBlockFlow {P} at (0,505.20) size 769x45
+        LayoutText {#text} at (0,0) size 757x45
+          text run at (0,0) width 476: "The first row should have three aqua stripes just inside the "
+          text run at (475,0) width 282: "bottom and right border edges of its"
+          text run at (0,15) width 219: "last cell. The bottom three "
+          text run at (218,15) width 516: "stripes should continue across the row, appearing along the border"
+          text run at (0,30) width 141: "edge of each cell."
+      LayoutBlockFlow {P} at (0,563.20) size 769x45
+        LayoutText {#text} at (0,0) size 765x45
+          text run at (0,0) width 469: "The second row should have three vertical aqua stripes just "
+          text run at (468,0) width 297: "inside the left border edge of the top"
+          text run at (0,15) width 227: "half of the first cell (Cell "
+          text run at (226,15) width 508: "E.) Three horizontal aqua stripes should cut across that cell and"
+          text run at (0,30) width 461: "align along the bottom border edge of the last three cells."
+      LayoutBlockFlow {P} at (0,621.20) size 769x30
+        LayoutText {#text} at (0,0) size 726x30
+          text run at (0,0) width 515: "The third row should have three horizontal aqua stripes along the "
+          text run at (514,0) width 212: "top border edge of the last"
+          text run at (0,15) width 180: "three cells in the row."
+      LayoutBlockFlow {DIV} at (0,664.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,698.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-expected.png
new file mode 100644
index 0000000..09640fe8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-expected.txt
new file mode 100644
index 0000000..9eacdc1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-expected.txt
@@ -0,0 +1,96 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 770
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x770 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x770.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x747.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 229x17
+          text run at (0,0) width 229: "Background on 'table-row'"
+      LayoutTable {TABLE} at (0,32.20) size 618x466 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x22
+          LayoutText {#text} at (163,0) size 292x22
+            text run at (163,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,23) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100 [bgcolor=#000000]
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,343) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (1,137) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108 [bgcolor=#000000]
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84 [bgcolor=#000000]
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,511.20) size 769x15
+        LayoutText {#text} at (0,0) size 172x15
+          text run at (0,0) width 172: "Three rows are styled."
+      LayoutBlockFlow {P} at (0,539.20) size 769x45
+        LayoutText {#text} at (0,0) size 757x45
+          text run at (0,0) width 476: "The first row should have three aqua stripes just inside the "
+          text run at (475,0) width 282: "bottom and right border edges of its"
+          text run at (0,15) width 219: "last cell. The bottom three "
+          text run at (218,15) width 516: "stripes should continue across the row, appearing along the border"
+          text run at (0,30) width 141: "edge of each cell."
+      LayoutBlockFlow {P} at (0,597.20) size 769x45
+        LayoutText {#text} at (0,0) size 765x45
+          text run at (0,0) width 469: "The second row should have three vertical aqua stripes just "
+          text run at (468,0) width 297: "inside the left border edge of the top"
+          text run at (0,15) width 227: "half of the first cell (Cell "
+          text run at (226,15) width 508: "E.) Three horizontal aqua stripes should cut across that cell and"
+          text run at (0,30) width 461: "align along the bottom border edge of the last three cells."
+      LayoutBlockFlow {P} at (0,655.20) size 769x30
+        LayoutText {#text} at (0,0) size 726x30
+          text run at (0,0) width 515: "The third row should have three horizontal aqua stripes along the "
+          text run at (514,0) width 212: "top border edge of the last"
+          text run at (0,15) width 180: "three cells in the row."
+      LayoutBlockFlow {DIV} at (0,698.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,732.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
new file mode 100644
index 0000000..cbde8c2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-collapsed-border-expected.txt
new file mode 100644
index 0000000..17739fa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-collapsed-border-expected.txt
@@ -0,0 +1,82 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 635
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x635 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x635.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x612.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 439x17
+          text run at (0,0) width 439: "crbug.com/35679: Background on 'table-row-group'"
+      LayoutTable {TABLE} at (0,32.20) size 578x432 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x22
+          LayoutText {#text} at (144,0) size 290x22
+            text run at (144,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,28) size 577x99 [bgcolor=#000000]
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,317) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,41) size 342x31 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 47x22
+                text run at (2,8) width 47: "TD M"
+            LayoutTableCell {TD} at (342,44) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (465,44) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (0,127) size 577x190 [bgcolor=#000000]
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,76) size 135x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (135,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (342,41) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (465,41) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,136) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (342,136) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (465,136) size 112x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,477.20) size 769x30
+        LayoutText {#text} at (0,0) size 734x30
+          text run at (0,0) width 734: "There should be three aqua stripes along the top border edge of each cell in the first row and"
+          text run at (0,15) width 554: "three stripes along the right border edge of the last cell in that row."
+      LayoutBlockFlow {P} at (0,520.20) size 769x30
+        LayoutText {#text} at (0,0) size 734x30
+          text run at (0,0) width 734: "There should be three aqua stripes along the bottom border edge of cells E, J, K, and L. There"
+          text run at (0,15) width 570: "should also be three vertical aqua stripes along the left edge of cell E."
+      LayoutBlockFlow {DIV} at (0,563.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,597.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-expected.png
new file mode 100644
index 0000000..1c0ce1e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-expected.txt
new file mode 100644
index 0000000..644fe9e0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-expected.txt
@@ -0,0 +1,82 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 669
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x669 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x669.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x646.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 439x17
+          text run at (0,0) width 439: "crbug.com/35679: Background on 'table-row-group'"
+      LayoutTable {TABLE} at (0,32.20) size 618x466 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x22
+          LayoutText {#text} at (163,0) size 292x22
+            text run at (163,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,23) size 616x114 [bgcolor=#000000]
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,343) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (1,137) size 616x206 [bgcolor=#000000]
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,511.20) size 769x30
+        LayoutText {#text} at (0,0) size 734x30
+          text run at (0,0) width 734: "There should be three aqua stripes along the top border edge of each cell in the first row and"
+          text run at (0,15) width 554: "three stripes along the right border edge of the last cell in that row."
+      LayoutBlockFlow {P} at (0,554.20) size 769x30
+        LayoutText {#text} at (0,0) size 734x30
+          text run at (0,0) width 734: "There should be three aqua stripes along the bottom border edge of cells E, J, K, and L. There"
+          text run at (0,15) width 570: "should also be three vertical aqua stripes along the left edge of cell E."
+      LayoutBlockFlow {DIV} at (0,597.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,631.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
new file mode 100644
index 0000000..c2faf54
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-collapsed-border-expected.txt
new file mode 100644
index 0000000..75824c4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-collapsed-border-expected.txt
@@ -0,0 +1,86 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 635
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x635 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x635.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x612.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 393x17
+          text run at (0,0) width 393: "crbug.com/35679: Background on 'table-cell'"
+      LayoutTable {TABLE} at (0,32.20) size 578x432 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x22
+          LayoutText {#text} at (144,0) size 290x22
+            text run at (144,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,28) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,317) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,41) size 342x31 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 47x22
+                text run at (2,8) width 47: "TD M"
+            LayoutTableCell {TD} at (342,44) size 123x25 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (465,44) size 112x25 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (0,127) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,76) size 135x37 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (135,38) size 207x31 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (342,41) size 123x25 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (465,41) size 112x25 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,136) size 207x25 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (342,136) size 123x25 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (465,136) size 112x25 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,477.20) size 769x30
+        LayoutText {#text} at (0,0) size 742x30
+          text run at (0,0) width 383: "Each cell's background should fill the rectangle "
+          text run at (382,0) width 360: "defined by its border edge. There should be no"
+          text run at (0,15) width 133: "gaps or holes in "
+          text run at (132,15) width 227: "the background within a cell."
+      LayoutBlockFlow {P} at (0,520.20) size 769x30
+        LayoutText {#text} at (0,0) size 734x30
+          text run at (0,0) width 313: "A purple band should align with the top "
+          text run at (312,0) width 422: "padding edge of each cell, and an orange stripe should"
+          text run at (0,15) width 63: "align a "
+          text run at (62,15) width 383: "few pixels to the left of its right padding edge."
+      LayoutBlockFlow {DIV} at (0,563.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,597.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-expected.png
new file mode 100644
index 0000000..73c740d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-expected.txt
new file mode 100644
index 0000000..3adfda4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-expected.txt
@@ -0,0 +1,86 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 669
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x669 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x669.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x646.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 393x17
+          text run at (0,0) width 393: "crbug.com/35679: Background on 'table-cell'"
+      LayoutTable {TABLE} at (0,32.20) size 618x466 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x22
+          LayoutText {#text} at (163,0) size 292x22
+            text run at (163,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,23) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [bgcolor=#000000] [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,343) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (1,137) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [bgcolor=#000000] [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,511.20) size 769x30
+        LayoutText {#text} at (0,0) size 742x30
+          text run at (0,0) width 383: "Each cell's background should fill the rectangle "
+          text run at (382,0) width 360: "defined by its border edge. There should be no"
+          text run at (0,15) width 133: "gaps or holes in "
+          text run at (132,15) width 227: "the background within a cell."
+      LayoutBlockFlow {P} at (0,554.20) size 769x30
+        LayoutText {#text} at (0,0) size 734x30
+          text run at (0,0) width 313: "A purple band should align with the top "
+          text run at (312,0) width 422: "padding edge of each cell, and an orange stripe should"
+          text run at (0,15) width 63: "align a "
+          text run at (62,15) width 383: "few pixels to the left of its right padding edge."
+      LayoutBlockFlow {DIV} at (0,597.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,631.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png
new file mode 100644
index 0000000..4cf080d2c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.txt
new file mode 100644
index 0000000..a828cd6a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.txt
@@ -0,0 +1,87 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 635
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x635 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x635.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x612.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 347x17
+          text run at (0,0) width 347: "crbug.com/35679: Background on 'table'"
+      LayoutTable {TABLE} at (0,32.20) size 578x432 [color=#FFFFFF] [bgcolor=#000000] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x22
+          LayoutText {#text} at (144,0) size 290x22
+            text run at (144,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,28) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,317) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,41) size 342x31 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 47x22
+                text run at (2,8) width 47: "TD M"
+            LayoutTableCell {TD} at (342,44) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (465,44) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (0,127) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,76) size 135x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (135,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (342,41) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (465,41) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,136) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (342,136) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (465,136) size 112x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,477.20) size 769x30
+        LayoutText {#text} at (0,0) size 734x30
+          text run at (0,0) width 367: "The table background should fill the rectangle "
+          text run at (366,0) width 368: "defined by the outer border of the table. There"
+          text run at (0,15) width 141: "should be no gaps "
+          text run at (140,15) width 446: "or holes in the background and the stripes should all be "
+          text run at (585,15) width 86: "continuous."
+      LayoutBlockFlow {P} at (0,520.20) size 769x30
+        LayoutText {#text} at (0,0) size 765x30
+          text run at (0,0) width 359: "A purple band should align with the left edge "
+          text run at (358,0) width 407: "of the painted area, and an aqua stripe should align"
+          text run at (0,15) width 102: "a few pixels "
+          text run at (101,15) width 165: "below the top border."
+      LayoutBlockFlow {DIV} at (0,563.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,597.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-collapsed-border-expected.png
new file mode 100644
index 0000000..6b9143a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-collapsed-border-expected.txt
new file mode 100644
index 0000000..4de5fbb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-collapsed-border-expected.txt
@@ -0,0 +1,96 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 708
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x708 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x708.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x685.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 411x17
+          text run at (0,0) width 411: "crbug.com/35679: Background on 'table-column'"
+      LayoutTable {TABLE} at (0,32.20) size 578x432 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x22
+          LayoutText {#text} at (144,0) size 290x22
+            text run at (144,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+        LayoutTableSection {THEAD} at (0,28) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,317) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,41) size 342x31 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 47x22
+                text run at (2,8) width 47: "TD M"
+            LayoutTableCell {TD} at (342,44) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (465,44) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (0,127) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,76) size 135x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (135,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (342,41) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (465,41) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,136) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (342,136) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (465,136) size 112x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,477.20) size 769x15
+        LayoutText {#text} at (0,0) size 219x15
+          text run at (0,0) width 219: "All four columns are styled."
+      LayoutBlockFlow {P} at (0,505.20) size 769x60
+        LayoutText {#text} at (0,0) size 749x60
+          text run at (0,0) width 414: "The table column background should be visible within "
+          text run at (413,0) width 336: "the border edge of each cell originating in"
+          text run at (0,15) width 157: "the column, and the "
+          text run at (156,15) width 508: "background should be continuously tiled to fill the entire cell. "
+          text run at (663,15) width 79: "Within the"
+          text run at (0,30) width 437: "column, all stripes should line up as if the cells were "
+          text run at (436,30) width 282: "cutouts in a stencil placed over the"
+          text run at (0,45) width 149: "column background. "
+          text run at (148,45) width 469: "Furthermore, horizontal stripes should align across columns."
+      LayoutBlockFlow {P} at (0,578.20) size 769x45
+        LayoutText {#text} at (0,0) size 757x45
+          text run at (0,0) width 313: "A red band should align with the bottom "
+          text run at (312,0) width 422: "border edge of the last cell in each column. An orange"
+          text run at (0,15) width 55: "stripe "
+          text run at (54,15) width 508: "should align a few pixels to the left of the right border of the "
+          text run at (561,15) width 196: "non-column-spanning cells"
+          text run at (0,30) width 118: "in each column."
+      LayoutBlockFlow {DIV} at (0,636.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,670.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-expected.png
new file mode 100644
index 0000000..543042c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-expected.txt
new file mode 100644
index 0000000..735ce03b1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-expected.txt
@@ -0,0 +1,96 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 742
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x742 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x742.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x719.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 411x17
+          text run at (0,0) width 411: "crbug.com/35679: Background on 'table-column'"
+      LayoutTable {TABLE} at (0,32.20) size 618x466 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x22
+          LayoutText {#text} at (163,0) size 292x22
+            text run at (163,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+        LayoutTableSection {THEAD} at (1,23) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,343) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (1,137) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,511.20) size 769x15
+        LayoutText {#text} at (0,0) size 219x15
+          text run at (0,0) width 219: "All four columns are styled."
+      LayoutBlockFlow {P} at (0,539.20) size 769x60
+        LayoutText {#text} at (0,0) size 749x60
+          text run at (0,0) width 414: "The table column background should be visible within "
+          text run at (413,0) width 336: "the border edge of each cell originating in"
+          text run at (0,15) width 157: "the column, and the "
+          text run at (156,15) width 508: "background should be continuously tiled to fill the entire cell. "
+          text run at (663,15) width 79: "Within the"
+          text run at (0,30) width 437: "column, all stripes should line up as if the cells were "
+          text run at (436,30) width 282: "cutouts in a stencil placed over the"
+          text run at (0,45) width 149: "column background. "
+          text run at (148,45) width 469: "Furthermore, horizontal stripes should align across columns."
+      LayoutBlockFlow {P} at (0,612.20) size 769x45
+        LayoutText {#text} at (0,0) size 757x45
+          text run at (0,0) width 313: "A red band should align with the bottom "
+          text run at (312,0) width 422: "border edge of the last cell in each column. An orange"
+          text run at (0,15) width 55: "stripe "
+          text run at (54,15) width 508: "should align a few pixels to the left of the right border of the "
+          text run at (561,15) width 196: "non-column-spanning cells"
+          text run at (0,30) width 118: "in each column."
+      LayoutBlockFlow {DIV} at (0,670.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,704.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
new file mode 100644
index 0000000..81456061
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-collapsed-border-expected.txt
new file mode 100644
index 0000000..fd34439e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-collapsed-border-expected.txt
@@ -0,0 +1,98 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 723
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x723 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x723.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x700.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 466x17
+          text run at (0,0) width 466: "crbug.com/35679: Background on 'table-column-group'"
+      LayoutTable {TABLE} at (0,32.20) size 578x432 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x22
+          LayoutText {#text} at (144,0) size 290x22
+            text run at (144,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,28) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,317) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,41) size 342x31 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 47x22
+                text run at (2,8) width 47: "TD M"
+            LayoutTableCell {TD} at (342,44) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (465,44) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (0,127) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,76) size 135x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (135,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (342,41) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (465,41) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,136) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (342,136) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (465,136) size 112x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,477.20) size 769x30
+        LayoutText {#text} at (0,0) size 742x30
+          text run at (0,0) width 352: "The first column group spans the first three "
+          text run at (351,0) width 391: "columns. The second column group only contains the"
+          text run at (0,15) width 94: "last column."
+      LayoutBlockFlow {P} at (0,520.20) size 769x60
+        LayoutText {#text} at (0,0) size 742x60
+          text run at (0,0) width 406: "The table column group background should be visible "
+          text run at (405,0) width 274: "within the border edge of each cell"
+          text run at (0,15) width 203: "originating in the column "
+          text run at (202,15) width 516: "group. Within each column group, all stripes should line up as if "
+          text run at (717,15) width 25: "the"
+          text run at (0,30) width 476: "cells were cutouts in a stencil placed over the column group "
+          text run at (475,30) width 220: "background. Furthermore, the"
+          text run at (0,45) width 289: "horizontal stripes should also align "
+          text run at (288,45) width 227: "across the two column groups."
+      LayoutBlockFlow {P} at (0,593.20) size 769x45
+        LayoutText {#text} at (0,0) size 757x45
+          text run at (0,0) width 367: "A purple band should align with the top border "
+          text run at (366,0) width 391: "edge of the cells in the first row. An aqua stripe"
+          text run at (0,15) width 118: "should align a "
+          text run at (117,15) width 500: "few pixels to the right of the left border edge of cells in the "
+          text run at (616,15) width 110: "column group's"
+          text run at (0,30) width 125: "leftmost column."
+      LayoutBlockFlow {DIV} at (0,651.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,685.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-expected.png
new file mode 100644
index 0000000..7cec1d8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-expected.txt
new file mode 100644
index 0000000..eeda6c3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-expected.txt
@@ -0,0 +1,98 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 757
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x757 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x757.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x734.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 466x17
+          text run at (0,0) width 466: "crbug.com/35679: Background on 'table-column-group'"
+      LayoutTable {TABLE} at (0,32.20) size 618x466 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x22
+          LayoutText {#text} at (163,0) size 292x22
+            text run at (163,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,23) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,343) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (1,137) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,511.20) size 769x30
+        LayoutText {#text} at (0,0) size 742x30
+          text run at (0,0) width 352: "The first column group spans the first three "
+          text run at (351,0) width 391: "columns. The second column group only contains the"
+          text run at (0,15) width 94: "last column."
+      LayoutBlockFlow {P} at (0,554.20) size 769x60
+        LayoutText {#text} at (0,0) size 742x60
+          text run at (0,0) width 406: "The table column group background should be visible "
+          text run at (405,0) width 274: "within the border edge of each cell"
+          text run at (0,15) width 203: "originating in the column "
+          text run at (202,15) width 516: "group. Within each column group, all stripes should line up as if "
+          text run at (717,15) width 25: "the"
+          text run at (0,30) width 476: "cells were cutouts in a stencil placed over the column group "
+          text run at (475,30) width 220: "background. Furthermore, the"
+          text run at (0,45) width 289: "horizontal stripes should also align "
+          text run at (288,45) width 227: "across the two column groups."
+      LayoutBlockFlow {P} at (0,627.20) size 769x45
+        LayoutText {#text} at (0,0) size 757x45
+          text run at (0,0) width 367: "A purple band should align with the top border "
+          text run at (366,0) width 391: "edge of the cells in the first row. An aqua stripe"
+          text run at (0,15) width 118: "should align a "
+          text run at (117,15) width 500: "few pixels to the right of the left border edge of cells in the "
+          text run at (616,15) width 110: "column group's"
+          text run at (0,30) width 125: "leftmost column."
+      LayoutBlockFlow {DIV} at (0,685.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,719.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-expected.png
new file mode 100644
index 0000000..024b62f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-expected.txt
new file mode 100644
index 0000000..35000a0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-expected.txt
@@ -0,0 +1,87 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 669
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x669 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x669.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x646.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 347x17
+          text run at (0,0) width 347: "crbug.com/35679: Background on 'table'"
+      LayoutTable {TABLE} at (0,32.20) size 618x466 [color=#FFFFFF] [bgcolor=#000000] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x22
+          LayoutText {#text} at (163,0) size 292x22
+            text run at (163,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,23) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,343) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (1,137) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,511.20) size 769x30
+        LayoutText {#text} at (0,0) size 734x30
+          text run at (0,0) width 367: "The table background should fill the rectangle "
+          text run at (366,0) width 368: "defined by the outer border of the table. There"
+          text run at (0,15) width 141: "should be no gaps "
+          text run at (140,15) width 446: "or holes in the background and the stripes should all be "
+          text run at (585,15) width 86: "continuous."
+      LayoutBlockFlow {P} at (0,554.20) size 769x30
+        LayoutText {#text} at (0,0) size 765x30
+          text run at (0,0) width 359: "A purple band should align with the left edge "
+          text run at (358,0) width 407: "of the painted area, and an aqua stripe should align"
+          text run at (0,15) width 102: "a few pixels "
+          text run at (101,15) width 165: "below the top border."
+      LayoutBlockFlow {DIV} at (0,597.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,631.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-collapsed-border-expected.png
new file mode 100644
index 0000000..b4aa2f4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-collapsed-border-expected.txt
new file mode 100644
index 0000000..f61805cf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-collapsed-border-expected.txt
@@ -0,0 +1,95 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 693
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x693 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x693.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x670.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 384x17
+          text run at (0,0) width 384: "crbug.com/35679: Background on 'table-row'"
+      LayoutTable {TABLE} at (0,32.20) size 578x432 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x22
+          LayoutText {#text} at (144,0) size 290x22
+            text run at (144,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,28) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99 [bgcolor=#000000]
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,317) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114 [bgcolor=#000000]
+            LayoutTableCell {TD} at (0,41) size 342x31 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 47x22
+                text run at (2,8) width 47: "TD M"
+            LayoutTableCell {TD} at (342,44) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (465,44) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (0,127) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107 [bgcolor=#000000]
+            LayoutTableCell {TD} at (0,76) size 135x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (135,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (342,41) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (465,41) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83 [bgcolor=#000000]
+            LayoutTableCell {TD} at (135,136) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (342,136) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (465,136) size 112x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,477.20) size 769x15
+        LayoutText {#text} at (0,0) size 196x15
+          text run at (0,0) width 196: "All four rows are styled."
+      LayoutBlockFlow {P} at (0,505.20) size 769x60
+        LayoutText {#text} at (0,0) size 765x60
+          text run at (0,0) width 391: "The table row background should be visible within "
+          text run at (390,0) width 367: "the border edge of each cell originating in the"
+          text run at (0,15) width 102: "row, and the "
+          text run at (101,15) width 508: "background should be continuously tiled to fill the entire cell. "
+          text run at (608,15) width 157: "Within each row, all"
+          text run at (0,30) width 344: "stripes should line up as if the cells were "
+          text run at (343,30) width 406: "cutouts in a stencil placed over the row background."
+          text run at (0,45) width 102: "Furthermore, "
+          text run at (101,45) width 329: "vertical stripes should align across rows."
+      LayoutBlockFlow {P} at (0,578.20) size 769x30
+        LayoutText {#text} at (0,0) size 765x30
+          text run at (0,0) width 352: "A red band should align with the left border "
+          text run at (351,0) width 414: "edge of the first cells in each row. An orange stripe"
+          text run at (0,15) width 102: "should align "
+          text run at (101,15) width 524: "a few pixels above the bottom border of the non-row-spanning cells "
+          text run at (624,15) width 94: "in each row."
+      LayoutBlockFlow {DIV} at (0,621.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,655.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-expected.png
new file mode 100644
index 0000000..7a75624
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-expected.txt
new file mode 100644
index 0000000..fbb1622
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-expected.txt
@@ -0,0 +1,95 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 727
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x727 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x727.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x704.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 384x17
+          text run at (0,0) width 384: "crbug.com/35679: Background on 'table-row'"
+      LayoutTable {TABLE} at (0,32.20) size 618x466 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x22
+          LayoutText {#text} at (163,0) size 292x22
+            text run at (163,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,23) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100 [bgcolor=#000000]
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,343) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115 [bgcolor=#000000]
+            LayoutTableCell {TD} at (7,44) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (1,137) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108 [bgcolor=#000000]
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84 [bgcolor=#000000]
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,511.20) size 769x15
+        LayoutText {#text} at (0,0) size 196x15
+          text run at (0,0) width 196: "All four rows are styled."
+      LayoutBlockFlow {P} at (0,539.20) size 769x60
+        LayoutText {#text} at (0,0) size 765x60
+          text run at (0,0) width 391: "The table row background should be visible within "
+          text run at (390,0) width 367: "the border edge of each cell originating in the"
+          text run at (0,15) width 102: "row, and the "
+          text run at (101,15) width 508: "background should be continuously tiled to fill the entire cell. "
+          text run at (608,15) width 157: "Within each row, all"
+          text run at (0,30) width 344: "stripes should line up as if the cells were "
+          text run at (343,30) width 406: "cutouts in a stencil placed over the row background."
+          text run at (0,45) width 102: "Furthermore, "
+          text run at (101,45) width 329: "vertical stripes should align across rows."
+      LayoutBlockFlow {P} at (0,612.20) size 769x30
+        LayoutText {#text} at (0,0) size 765x30
+          text run at (0,0) width 352: "A red band should align with the left border "
+          text run at (351,0) width 414: "edge of the first cells in each row. An orange stripe"
+          text run at (0,15) width 102: "should align "
+          text run at (101,15) width 524: "a few pixels above the bottom border of the non-row-spanning cells "
+          text run at (624,15) width 94: "in each row."
+      LayoutBlockFlow {DIV} at (0,655.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,689.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
new file mode 100644
index 0000000..d8ae2f6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-collapsed-border-expected.txt
new file mode 100644
index 0000000..105380471
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-collapsed-border-expected.txt
@@ -0,0 +1,94 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 693
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x693 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x693.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x670.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 439x17
+          text run at (0,0) width 439: "crbug.com/35679: Background on 'table-row-group'"
+      LayoutTable {TABLE} at (0,32.20) size 578x432 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x22
+          LayoutText {#text} at (144,0) size 290x22
+            text run at (144,0) width 290: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,28) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x22
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,317) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,41) size 342x31 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 47x22
+                text run at (2,8) width 47: "TD M"
+            LayoutTableCell {TD} at (342,44) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (465,44) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (0,127) size 577x190 [bgcolor=#000000]
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,76) size 135x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 44x22
+                text run at (8,8) width 44: "TD E"
+            LayoutTableCell {TD} at (135,38) size 207x31 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 43x22
+                text run at (8,8) width 43: "TD F"
+            LayoutTableCell {TD} at (342,41) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (465,41) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,136) size 207x25 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 42x22
+                text run at (8,2) width 42: "TD J"
+            LayoutTableCell {TD} at (342,136) size 123x25 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (465,136) size 112x25 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,477.20) size 769x15
+        LayoutText {#text} at (0,0) size 414x15
+          text run at (0,0) width 375: "The styled row group spans the second and third "
+          text run at (374,0) width 40: "rows."
+      LayoutBlockFlow {P} at (0,505.20) size 769x45
+        LayoutText {#text} at (0,0) size 765x45
+          text run at (0,0) width 383: "The table row group background should be visible "
+          text run at (382,0) width 367: "within the border edge of each cell originating"
+          text run at (0,15) width 141: "in the row group. "
+          text run at (140,15) width 477: "All stripes should line up as if the cells were cutouts in a "
+          text run at (616,15) width 149: "stencil placed over"
+          text run at (0,30) width 196: "the row group background."
+      LayoutBlockFlow {P} at (0,563.20) size 769x45
+        LayoutText {#text} at (0,0) size 749x45
+          text run at (0,0) width 352: "A red band should align with the left border "
+          text run at (351,0) width 391: "edge of the first cells in each of the row group's"
+          text run at (0,15) width 125: "rows. An orange "
+          text run at (124,15) width 501: "stripe should align a few pixels above the bottom border of the "
+          text run at (624,15) width 125: "cells in the row"
+          text run at (0,30) width 133: "group's last row."
+      LayoutBlockFlow {DIV} at (0,621.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,655.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-expected.png
new file mode 100644
index 0000000..89fca61
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-expected.txt
new file mode 100644
index 0000000..d2b89b6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-expected.txt
@@ -0,0 +1,94 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 727
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x727 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x727.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x704.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 439x17
+          text run at (0,0) width 439: "crbug.com/35679: Background on 'table-row-group'"
+      LayoutTable {TABLE} at (0,32.20) size 618x466 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x22
+          LayoutText {#text} at (163,0) size 292x22
+            text run at (163,0) width 292: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,23) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x22
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x22
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x22
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x22
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,343) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,44) size 357x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 47x22
+                text run at (2,2) width 47: "TD M"
+            LayoutTableCell {TD} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD O"
+            LayoutTableCell {TD} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 44x22
+                text run at (2,2) width 44: "TD P"
+        LayoutTableSection {TBODY} at (1,137) size 616x206 [bgcolor=#000000]
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,74) size 130x50 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 44x22
+                text run at (14,14) width 44: "TD E"
+            LayoutTableCell {TD} at (144,41) size 220x26 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD F"
+            LayoutTableCell {TD} at (371,41) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 46x22
+                text run at (2,2) width 46: "TD G"
+            LayoutTableCell {TD} at (496,41) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,144) size 220x26 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 42x22
+                text run at (2,2) width 42: "TD J"
+            LayoutTableCell {TD} at (371,144) size 118x26 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 45x22
+                text run at (2,2) width 45: "TD K"
+            LayoutTableCell {TD} at (496,144) size 113x26 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 43x22
+                text run at (2,2) width 43: "TD L"
+      LayoutBlockFlow {P} at (0,511.20) size 769x15
+        LayoutText {#text} at (0,0) size 414x15
+          text run at (0,0) width 375: "The styled row group spans the second and third "
+          text run at (374,0) width 40: "rows."
+      LayoutBlockFlow {P} at (0,539.20) size 769x45
+        LayoutText {#text} at (0,0) size 765x45
+          text run at (0,0) width 383: "The table row group background should be visible "
+          text run at (382,0) width 367: "within the border edge of each cell originating"
+          text run at (0,15) width 141: "in the row group. "
+          text run at (140,15) width 477: "All stripes should line up as if the cells were cutouts in a "
+          text run at (616,15) width 149: "stencil placed over"
+          text run at (0,30) width 196: "the row group background."
+      LayoutBlockFlow {P} at (0,597.20) size 769x45
+        LayoutText {#text} at (0,0) size 749x45
+          text run at (0,0) width 352: "A red band should align with the left border "
+          text run at (351,0) width 391: "edge of the first cells in each of the row group's"
+          text run at (0,15) width 125: "rows. An orange "
+          text run at (124,15) width 501: "stripe should align a few pixels above the bottom border of the "
+          text run at (624,15) width 125: "cells in the row"
+          text run at (0,30) width 133: "group's last row."
+      LayoutBlockFlow {DIV} at (0,655.20) size 769x34
+        LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,689.20) size 769x15
+        LayoutText {#text} at (0,0) size 687x15
+          text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/tbody-background-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/tbody-background-image-expected.png
new file mode 100644
index 0000000..0f13c2c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/tbody-background-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/tbody-background-image-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/table/tbody-background-image-expected.txt
new file mode 100644
index 0000000..1938a64
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/tbody-background-image-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x462
+  LayoutBlockFlow {HTML} at (0,0) size 800x462
+    LayoutBlockFlow {BODY} at (8,16) size 784x438
+      LayoutBlockFlow {P} at (0,0) size 784x18
+        LayoutText {#text} at (0,0) size 394x18
+          text run at (0,0) width 394: "crbug.com/35697: The image should be tiled across the table."
+      LayoutTable {TABLE} at (0,34) size 784x404
+        LayoutTableSection {TBODY} at (0,0) size 784x404
+          LayoutTableRow {TR} at (0,0) size 784x202
+            LayoutTableCell {TD} at (0,100) size 392x2 [r=0 c=0 rs=1 cs=1]
+            LayoutTableCell {TD} at (392,100) size 392x2 [r=0 c=1 rs=1 cs=1]
+          LayoutTableRow {TR} at (0,202) size 784x202
+            LayoutTableCell {TD} at (0,302) size 392x2 [r=1 c=0 rs=1 cs=1]
+            LayoutTableCell {TD} at (392,302) size 392x2 [r=1 c=1 rs=1 cs=1]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index 1963ea1..643731e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.txt
index 25b4c8647..ac73e27 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.txt
@@ -1,41 +1,41 @@
-layer at (0,0) size 800x600 scrollWidth 1506 scrollHeight 1660
+layer at (0,0) size 800x600 clip at (0,0) size 785x585 scrollWidth 1506 scrollHeight 1660
   LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x1660 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x1660.19
-    LayoutBlockFlow {BODY} at (8,17.41) size 784x1629.78 [color=#00FF00] [bgcolor=#333333]
-      LayoutBlockFlow {H1} at (0,0) size 784x30
+layer at (0,0) size 785x1660 backgroundClip at (0,0) size 785x585 clip at (0,0) size 785x585
+  LayoutBlockFlow {HTML} at (0,0) size 785x1660.19
+    LayoutBlockFlow {BODY} at (8,17.41) size 769x1629.78 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H1} at (0,0) size 769x30
         LayoutText {#text} at (0,0) size 515x30
           text run at (0,0) width 515: "CSS2 Table Backgrounds Test Suite"
-      LayoutBlockFlow {H2} at (0,47.41) size 784x23
+      LayoutBlockFlow {H2} at (0,47.41) size 769x23
         LayoutText {#text} at (0,0) size 246x23
           text run at (0,0) width 246: "Part E: Special Tests"
-      LayoutBlockFlow {H3} at (0,86.58) size 784x17
+      LayoutBlockFlow {H3} at (0,86.58) size 769x17
         LayoutText {#text} at (0,0) size 156x17
           text run at (0,0) width 156: "Fixed Backgrounds"
-      LayoutBlockFlow {UL} at (0,118.78) size 784x60
-        LayoutListItem {LI} at (40,0) size 744x45
+      LayoutBlockFlow {UL} at (0,118.78) size 769x60
+        LayoutListItem {LI} at (40,0) size 729x45
           LayoutListMarker (anonymous) at (-16,0) size 6x15: bullet
-          LayoutText {#text} at (0,0) size 742x45
-            text run at (0,0) width 742: "If you scroll the table over the top left corner of the viewport, the first, second, and fourth"
-            text run at (0,15) width 718: "rows as well as cell L should reveal a purple and aqua band forming a 90-degree angle in the"
-            text run at (0,30) width 125: "top left corner."
-        LayoutListItem {LI} at (40,45) size 744x15
+          LayoutText {#text} at (0,0) size 718x45
+            text run at (0,0) width 687: "If you scroll the table over the top left corner of the viewport, the first, second, and"
+            text run at (0,15) width 718: "fourth rows as well as cell L should reveal a purple and aqua band forming a 90-degree angle"
+            text run at (0,30) width 180: "in the top left corner."
+        LayoutListItem {LI} at (40,45) size 729x15
           LayoutListMarker (anonymous) at (-16,0) size 6x15: bullet
           LayoutText {#text} at (0,0) size 648x15
             text run at (0,0) width 648: "Cells A and P should have a rainbow background that seems attached to the viewport."
-      LayoutBlockFlow {DL} at (0,191.78) size 784x60
-        LayoutBlockFlow {DT} at (0,0) size 784x15
+      LayoutBlockFlow {DL} at (0,191.78) size 769x60
+        LayoutBlockFlow {DT} at (0,0) size 769x15
           LayoutText {#text} at (0,0) size 63x15
             text run at (0,0) width 63: "previous"
-        LayoutBlockFlow {DD} at (40,15) size 744x15
+        LayoutBlockFlow {DD} at (40,15) size 729x15
           LayoutInline {A} at (0,0) size 172x15 [color=#FFFF00]
             LayoutText {#text} at (0,0) size 172x15
               text run at (0,0) width 172: "Special Tests: opacity"
           LayoutText {#text} at (0,0) size 0x0
-        LayoutBlockFlow {DT} at (0,30) size 784x15
+        LayoutBlockFlow {DT} at (0,30) size 769x15
           LayoutText {#text} at (0,0) size 63x15
             text run at (0,0) width 63: "contents"
-        LayoutBlockFlow {DD} at (40,45) size 744x15
+        LayoutBlockFlow {DD} at (40,45) size 729x15
           LayoutInline {A} at (0,0) size 133x15 [color=#FFFF00]
             LayoutText {#text} at (0,0) size 133x15
               text run at (0,0) width 133: "Table of Contents"
@@ -154,14 +154,14 @@
             LayoutTableCell {TD} at (465,136) size 112x25 [border: (1px dotted #000000)] [r=1 c=3 rs=1 cs=1]
               LayoutText {#text} at (2,2) size 43x22
                 text run at (2,2) width 43: "TD L"
-      LayoutBlockFlow {DIV} at (0,1162.78) size 784x34
+      LayoutBlockFlow {DIV} at (0,1162.78) size 769x34
         LayoutInline {A} at (0,0) size 88x15 [color=#FFFF00]
           LayoutImage {IMG} at (0,0) size 88x31
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {ADDRESS} at (0,1196.78) size 784x15
+      LayoutBlockFlow {ADDRESS} at (0,1196.78) size 769x15
         LayoutText {#text} at (0,0) size 687x15
           text run at (0,0) width 687: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
-      LayoutBlockFlow {PRE} at (0,1224.78) size 784x405
+      LayoutBlockFlow {PRE} at (0,1224.78) size 769x405
         LayoutText {#text} at (0,0) size 1498x405
           text run at (0,0) width 1498: "................................................................................................................................................................................................"
           text run at (1497,0) width 1: " "
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png
index 07da042..3957d38 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-transform-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-transform-expected.png
index f09bdf14..5574224 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-cell-collapsed-border-expected.png
new file mode 100644
index 0000000..452acf0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-cell-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-cell-collapsed-border-expected.txt
new file mode 100644
index 0000000..d60a5d1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-cell-collapsed-border-expected.txt
@@ -0,0 +1,83 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 650
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x650 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x650.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x627.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 387x17
+          text run at (0,0) width 387: "crbug.com/35679: Background on 'table-cell'"
+      LayoutTable {TABLE} at (0,32.20) size 586x443 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 586x27
+          LayoutText {#text} at (127,0) size 332x27
+            text run at (127,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (2,33) size 581x101
+          LayoutTableRow {TR} at (0,0) size 581x101
+            LayoutTableCell {TH} at (0,34) size 137x33 [border: (3px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (44,4) size 46x21
+                text run at (44,4) width 46: "TH A"
+            LayoutTableCell {TH} at (137,32) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (344,37) size 123x27 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,4) size 46x21
+                text run at (42,4) width 46: "TH C"
+            LayoutTableCell {TH} at (467,37) size 114x27 [border: (3px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,4) size 45x21
+                text run at (34,4) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (2,324) size 581x116
+          LayoutTableRow {TR} at (0,0) size 581x116
+            LayoutTableCell {TD} at (0,39) size 344x38 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (4,8) size 54x27
+                text run at (4,8) width 54: "TD M"
+            LayoutTableCell {TD} at (344,42) size 123x32 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (467,42) size 114x32 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (2,134) size 581x190
+          LayoutTableRow {TR} at (0,0) size 581x107
+            LayoutTableCell {TD} at (0,74) size 137x42 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (137,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (344,38) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (467,38) size 114x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 581x83
+            LayoutTableCell {TD} at (137,133) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (344,133) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (467,133) size 114x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,488.20) size 769x16
+        LayoutText {#text} at (0,0) size 168x16
+          text run at (0,0) width 168: "Two cells are styled."
+      LayoutBlockFlow {P} at (0,517.20) size 769x16
+        LayoutText {#text} at (0,0) size 704x16
+          text run at (0,0) width 704: "There should be three aqua stripes just inside the top and left padding edges of cell E."
+      LayoutBlockFlow {P} at (0,546.20) size 769x16
+        LayoutText {#text} at (0,0) size 728x16
+          text run at (0,0) width 728: "There should be three aqua stripes just inside the bottom and right padding edges of Cell M"
+      LayoutBlockFlow {DIV} at (0,575.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,610.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-cell-expected.png
new file mode 100644
index 0000000..1e80999
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-cell-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-cell-expected.txt
new file mode 100644
index 0000000..c2ad340
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-cell-expected.txt
@@ -0,0 +1,83 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 686
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x686 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x686.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x663.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 387x17
+          text run at (0,0) width 387: "crbug.com/35679: Background on 'table-cell'"
+      LayoutTable {TABLE} at (0,32.20) size 626x479 [color=#FFFFFF] [border: (5px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 626x27
+          LayoutText {#text} at (145,0) size 336x27
+            text run at (145,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (5,32) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (5,352) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (5,146) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [bgcolor=#000000] [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,524.20) size 769x16
+        LayoutText {#text} at (0,0) size 168x16
+          text run at (0,0) width 168: "Two cells are styled."
+      LayoutBlockFlow {P} at (0,553.20) size 769x16
+        LayoutText {#text} at (0,0) size 704x16
+          text run at (0,0) width 704: "There should be three aqua stripes just inside the top and left padding edges of cell E."
+      LayoutBlockFlow {P} at (0,582.20) size 769x16
+        LayoutText {#text} at (0,0) size 728x16
+          text run at (0,0) width 728: "There should be three aqua stripes just inside the bottom and right padding edges of Cell M"
+      LayoutBlockFlow {DIV} at (0,611.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,646.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-collapsed-border-expected.png
new file mode 100644
index 0000000..f51433d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-collapsed-border-expected.txt
new file mode 100644
index 0000000..baaa927
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-collapsed-border-expected.txt
@@ -0,0 +1,77 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x579
+  LayoutBlockFlow {HTML} at (0,0) size 800x579.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 784x556.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 784x17
+        LayoutText {#text} at (0,0) size 189x17
+          text run at (0,0) width 189: "Background on 'table'"
+      LayoutBlockFlow {P} at (0,32.20) size 784x16
+        LayoutText {#text} at (0,0) size 656x16
+          text run at (0,0) width 656: "There should be three aqua stripes just inside the bottom and right table borders."
+      LayoutTable {TABLE} at (0,61.20) size 586x443 [color=#FFFFFF] [bgcolor=#000000] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 586x27
+          LayoutText {#text} at (127,0) size 332x27
+            text run at (127,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (2,33) size 581x101
+          LayoutTableRow {TR} at (0,0) size 581x101
+            LayoutTableCell {TH} at (0,34) size 137x33 [border: (3px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (44,4) size 46x21
+                text run at (44,4) width 46: "TH A"
+            LayoutTableCell {TH} at (137,32) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (344,37) size 123x27 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,4) size 46x21
+                text run at (42,4) width 46: "TH C"
+            LayoutTableCell {TH} at (467,37) size 114x27 [border: (3px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,4) size 45x21
+                text run at (34,4) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (2,324) size 581x116
+          LayoutTableRow {TR} at (0,0) size 581x116
+            LayoutTableCell {TD} at (0,39) size 344x38 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (4,8) size 54x27
+                text run at (4,8) width 54: "TD M"
+            LayoutTableCell {TD} at (344,42) size 123x32 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (467,42) size 114x32 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (2,134) size 581x190
+          LayoutTableRow {TR} at (0,0) size 581x107
+            LayoutTableCell {TD} at (0,74) size 137x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (137,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (344,38) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (467,38) size 114x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 581x83
+            LayoutTableCell {TD} at (137,133) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (344,133) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (467,133) size 114x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {DIV} at (0,504.20) size 784x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,539.20) size 784x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-collapsed-border-expected.png
new file mode 100644
index 0000000..300396f2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-collapsed-border-expected.txt
new file mode 100644
index 0000000..4059ce2e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-collapsed-border-expected.txt
@@ -0,0 +1,96 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 837
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x837 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x837.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x814.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 405x17
+          text run at (0,0) width 405: "crbug.com/35697: Background on 'table-column'"
+      LayoutTable {TABLE} at (0,32.20) size 588x441 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 588x27
+          LayoutText {#text} at (128,0) size 332x27
+            text run at (128,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000] [border: (9px dashed #FFFFFF)]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (2,33) size 584x100
+          LayoutTableRow {TR} at (0,0) size 584x100
+            LayoutTableCell {TH} at (0,33) size 137x33 [border: (3px dashed #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (44,4) size 46x21
+                text run at (44,4) width 46: "TH A"
+            LayoutTableCell {TH} at (137,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (344,35) size 125x29 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,4) size 46x21
+                text run at (42,4) width 46: "TH C"
+            LayoutTableCell {TH} at (469,37) size 115x26 [border: (2px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (36,3) size 45x21
+                text run at (36,3) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (2,323) size 584x115
+          LayoutTableRow {TR} at (0,0) size 584x115
+            LayoutTableCell {TD} at (0,38) size 344x38 [border: (7px dashed #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (4,8) size 54x27
+                text run at (4,8) width 54: "TD M"
+            LayoutTableCell {TD} at (344,41) size 125x32 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,2) size 52x27
+                text run at (6,2) width 52: "TD O"
+            LayoutTableCell {TD} at (469,42) size 115x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (4,2) size 50x27
+                text run at (4,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (2,133) size 584x190
+          LayoutTableRow {TR} at (0,0) size 584x107
+            LayoutTableCell {TD} at (0,74) size 137x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (137,33) size 207x40 [border: (7px dashed #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (344,36) size 125x34 [border: (3px dashed #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,4) size 52x27
+                text run at (6,4) width 52: "TD G"
+            LayoutTableCell {TD} at (469,38) size 115x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (4,2) size 52x27
+                text run at (4,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 584x83
+            LayoutTableCell {TD} at (137,130) size 207x36 [border: (5px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,6) size 48x27
+                text run at (8,6) width 48: "TD J"
+            LayoutTableCell {TD} at (344,132) size 125x32 [border: (3px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,4) size 52x27
+                text run at (6,4) width 52: "TD K"
+            LayoutTableCell {TD} at (469,133) size 115x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (4,2) size 48x27
+                text run at (4,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,486.20) size 769x16
+        LayoutText {#text} at (0,0) size 200x16
+          text run at (0,0) width 200: "Three columns are styled."
+      LayoutBlockFlow {P} at (0,515.20) size 769x112
+        LayoutText {#text} at (0,0) size 768x112
+          text run at (0,0) width 760: "In the first column, there should be three vertical stripes along the padding edge of the first"
+          text run at (0,16) width 744: "cell, continuing down through the column. (In cell E, the aqua stripe will be obscured by the"
+          text run at (0,32) width 760: "thicker right border.) The stripes will cut across cell E as well, but will be further obscured"
+          text run at (0,48) width 768: "by its thick border. In the border-collapsed table, the same will happen to the vertical stripes"
+          text run at (0,64) width 760: "in cell A due to cell B's thick border. The stripes should continue in the last cell, turning a"
+          text run at (0,80) width 752: "right angle to the left into three aqua stripes along the bottom border edge of the last cell."
+          text run at (0,96) width 624: "The last cell (M) should not have three vertical stripes along its right edge."
+      LayoutBlockFlow {P} at (0,640.20) size 769x48
+        LayoutText {#text} at (0,0) size 768x48
+          text run at (0,0) width 768: "In the second column, three vertical strips should run along the right of the first three cells,"
+          text run at (0,16) width 760: "aligning along cell F's right padding edge. (The stripes will be partially obscured by cell B's"
+          text run at (0,32) width 112: "thick border.)"
+      LayoutBlockFlow {P} at (0,701.20) size 769x48
+        LayoutText {#text} at (0,0) size 736x48
+          text run at (0,0) width 736: "In the third column, there should be three vertical stripes should run across the top of the"
+          text run at (0,16) width 712: "first cell and down the left of the column, aligning along cell K's left padding edge. In"
+          text run at (0,32) width 632: "border-collapse mode, they will be partially obscured by cell B's thick border."
+      LayoutBlockFlow {DIV} at (0,762.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,797.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-expected.png
new file mode 100644
index 0000000..1193e13
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-expected.txt
new file mode 100644
index 0000000..823e8d5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-expected.txt
@@ -0,0 +1,96 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 871
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x871 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x871.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x848.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 405x17
+          text run at (0,0) width 405: "crbug.com/35679: Background on 'table-column'"
+      LayoutTable {TABLE} at (0,32.20) size 630x475 [color=#FFFFFF] [border: (3px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 630x27
+          LayoutText {#text} at (147,0) size 336x27
+            text run at (147,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000] [border: (9px dashed #FFFFFF)]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (3,30) size 624x114
+          LayoutTableRow {TR} at (0,7) size 624x100
+            LayoutTableCell {TH} at (7,40) size 138x34 [border: (5px dashed #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (46,6) size 46x21
+                text run at (46,6) width 46: "TH A"
+            LayoutTableCell {TH} at (152,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (379,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (504,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (3,350) size 624x122
+          LayoutTableRow {TR} at (0,0) size 624x115
+            LayoutTableCell {TD} at (7,38) size 365x39 [border: (5px dashed #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (6,6) size 54x27
+                text run at (6,6) width 54: "TD M"
+            LayoutTableCell {TD} at (379,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (504,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (3,144) size 624x206
+          LayoutTableRow {TR} at (0,0) size 624x108
+            LayoutTableCell {TD} at (7,72) size 138x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (152,30) size 220x47 [border: (9px dashed #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (10,10) size 48x27
+                text run at (10,10) width 48: "TD F"
+            LayoutTableCell {TD} at (379,34) size 118x39 [border: (5px dashed #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 52x27
+                text run at (6,6) width 52: "TD G"
+            LayoutTableCell {TD} at (504,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 624x84
+            LayoutTableCell {TD} at (152,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (379,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (504,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,520.20) size 769x16
+        LayoutText {#text} at (0,0) size 200x16
+          text run at (0,0) width 200: "Three columns are styled."
+      LayoutBlockFlow {P} at (0,549.20) size 769x112
+        LayoutText {#text} at (0,0) size 768x112
+          text run at (0,0) width 760: "In the first column, there should be three vertical stripes along the padding edge of the first"
+          text run at (0,16) width 744: "cell, continuing down through the column. (In cell E, the aqua stripe will be obscured by the"
+          text run at (0,32) width 760: "thicker right border.) The stripes will cut across cell E as well, but will be further obscured"
+          text run at (0,48) width 768: "by its thick border. In the border-collapsed table, the same will happen to the vertical stripes"
+          text run at (0,64) width 760: "in cell A due to cell B's thick border. The stripes should continue in the last cell, turning a"
+          text run at (0,80) width 752: "right angle to the left into three aqua stripes along the bottom border edge of the last cell."
+          text run at (0,96) width 624: "The last cell (M) should not have three vertical stripes along its right edge."
+      LayoutBlockFlow {P} at (0,674.20) size 769x48
+        LayoutText {#text} at (0,0) size 768x48
+          text run at (0,0) width 768: "In the second column, three vertical strips should run along the right of the first three cells,"
+          text run at (0,16) width 760: "aligning along cell F's right padding edge. (The stripes will be partially obscured by cell B's"
+          text run at (0,32) width 112: "thick border.)"
+      LayoutBlockFlow {P} at (0,735.20) size 769x48
+        LayoutText {#text} at (0,0) size 736x48
+          text run at (0,0) width 736: "In the third column, there should be three vertical stripes should run across the top of the"
+          text run at (0,16) width 712: "first cell and down the left of the column, aligning along cell K's left padding edge. In"
+          text run at (0,32) width 632: "border-collapse mode, they will be partially obscured by cell B's thick border."
+      LayoutBlockFlow {DIV} at (0,796.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,831.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
new file mode 100644
index 0000000..29d2d283
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-group-collapsed-border-expected.txt
new file mode 100644
index 0000000..f4afa26
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-group-collapsed-border-expected.txt
@@ -0,0 +1,80 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 667
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x667 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x667.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x644.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 459x17
+          text run at (0,0) width 459: "crbug.com/35679: Background on 'table-column-group'"
+      LayoutTable {TABLE} at (0,32.20) size 591x441 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 591x27
+          LayoutText {#text} at (130,0) size 331x27
+            text run at (130,0) width 331: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [border: (9px dashed #FFFFFF)]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,33) size 588x100
+          LayoutTableRow {TR} at (0,0) size 588x100
+            LayoutTableCell {TH} at (0,33) size 137x33 [border: (3px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (44,4) size 46x21
+                text run at (44,4) width 46: "TH A"
+            LayoutTableCell {TH} at (137,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (344,34) size 127x31 [border: (5px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,6) size 46x21
+                text run at (42,6) width 46: "TH C"
+            LayoutTableCell {TH} at (471,37) size 117x26 [border: (2px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (38,3) size 45x21
+                text run at (38,3) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,323) size 588x115
+          LayoutTableRow {TR} at (0,0) size 588x115
+            LayoutTableCell {TD} at (0,38) size 471x38 [border: (7px dashed #FFFFFF)] [r=0 c=0 rs=1 cs=3]
+              LayoutText {#text} at (4,8) size 54x27
+                text run at (4,8) width 54: "TD M"
+            LayoutTableCell {TD} at (471,42) size 117x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (6,2) size 50x27
+                text run at (6,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (1,133) size 588x190
+          LayoutTableRow {TR} at (0,0) size 588x107
+            LayoutTableCell {TD} at (0,74) size 137x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (137,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (344,36) size 127x34 [border: (3px dashed #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,4) size 52x27
+                text run at (6,4) width 52: "TD G"
+            LayoutTableCell {TD} at (471,38) size 117x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (6,2) size 52x27
+                text run at (6,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 588x83
+            LayoutTableCell {TD} at (137,132) size 207x32 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (344,131) size 127x34 [border: (3px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,4) size 52x27
+                text run at (6,4) width 52: "TD K"
+            LayoutTableCell {TD} at (471,133) size 117x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (6,2) size 48x27
+                text run at (6,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,486.20) size 769x48
+        LayoutText {#text} at (0,0) size 752x48
+          text run at (0,0) width 752: "Three aqua stripes should run along the bottom of the last cell in the first three columns and"
+          text run at (0,16) width 744: "up along the right edge of the cells in the third column. The stripes should align to be just"
+          text run at (0,32) width 328: "inside the padding edge in cells M and G."
+      LayoutBlockFlow {P} at (0,547.20) size 769x32
+        LayoutText {#text} at (0,0) size 736x32
+          text run at (0,0) width 736: "Three aqua stripes should also run just inside the top padding edge of the first cell in the"
+          text run at (0,16) width 560: "last column and down the left border edge of each cell in that column."
+      LayoutBlockFlow {DIV} at (0,592.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,627.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-group-expected.png
new file mode 100644
index 0000000..e6c55813
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-group-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-group-expected.txt
new file mode 100644
index 0000000..640599b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-column-group-expected.txt
@@ -0,0 +1,83 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 701
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x701 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x701.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x678.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 459x17
+          text run at (0,0) width 459: "crbug.com/35679: Background on 'table-column-group'"
+      LayoutTable {TABLE} at (0,32.20) size 622x475 [color=#FFFFFF] [border: (3px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 622x27
+          LayoutText {#text} at (143,0) size 336x27
+            text run at (143,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [border: (9px dashed #FFFFFF)]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (3,30) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (3,350) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,38) size 357x39 [border: (5px dashed #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (6,6) size 54x27
+                text run at (6,6) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (3,144) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,34) size 118x39 [border: (5px dashed #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 52x27
+                text run at (6,6) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,520.20) size 769x48
+        LayoutText {#text} at (0,0) size 752x48
+          text run at (0,0) width 752: "Three aqua stripes should run along the bottom of the last cell in the first three columns and"
+          text run at (0,16) width 744: "up along the right edge of the cells in the third column. The stripes should align to be just"
+          text run at (0,32) width 328: "inside the padding edge in cells M and G."
+      LayoutBlockFlow {P} at (0,581.20) size 769x32
+        LayoutText {#text} at (0,0) size 736x32
+          text run at (0,0) width 736: "Three aqua stripes should also run just inside the top padding edge of the first cell in the"
+          text run at (0,16) width 560: "last column and down the left border edge of each cell in that column."
+      LayoutBlockFlow {DIV} at (0,626.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,661.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-expected.png
new file mode 100644
index 0000000..4509778
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-expected.txt
new file mode 100644
index 0000000..ec531ff8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-expected.txt
@@ -0,0 +1,77 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 615
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x615 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x615.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x592.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 189x17
+          text run at (0,0) width 189: "Background on 'table'"
+      LayoutBlockFlow {P} at (0,32.20) size 769x16
+        LayoutText {#text} at (0,0) size 656x16
+          text run at (0,0) width 656: "There should be three aqua stripes just inside the bottom and right table borders."
+      LayoutTable {TABLE} at (0,61.20) size 626x479 [color=#FFFFFF] [bgcolor=#000000] [border: (5px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 626x27
+          LayoutText {#text} at (145,0) size 336x27
+            text run at (145,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (5,32) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TBODY} at (5,146) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+        LayoutTableSection {TFOOT} at (5,352) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+      LayoutBlockFlow {DIV} at (0,540.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,575.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-quirks-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
new file mode 100644
index 0000000..8bb0538
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-quirks-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-quirks-collapsed-border-expected.txt
new file mode 100644
index 0000000..4e833ba
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-quirks-collapsed-border-expected.txt
@@ -0,0 +1,77 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 784x17
+        LayoutText {#text} at (0,0) size 342x17
+          text run at (0,0) width 342: "crbug.com/35679: Background on 'table'"
+      LayoutBlockFlow {P} at (0,32.20) size 784x16
+        LayoutText {#text} at (0,0) size 656x16
+          text run at (0,0) width 656: "There should be three aqua stripes just inside the bottom and right table borders."
+      LayoutTable {TABLE} at (0,61.20) size 586x427 [color=#FFFFFF] [bgcolor=#000000] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 586x27
+          LayoutText {#text} at (127,0) size 332x27
+            text run at (127,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (2,33) size 581x96
+          LayoutTableRow {TR} at (0,0) size 581x96
+            LayoutTableCell {TH} at (0,31) size 137x33 [border: (3px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (44,4) size 46x21
+                text run at (44,4) width 46: "TH A"
+            LayoutTableCell {TH} at (137,29) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (344,34) size 123x27 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,4) size 46x21
+                text run at (42,4) width 46: "TH C"
+            LayoutTableCell {TH} at (467,34) size 114x27 [border: (3px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,4) size 45x21
+                text run at (34,4) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (2,313) size 581x111
+          LayoutTableRow {TR} at (0,0) size 581x111
+            LayoutTableCell {TD} at (0,36) size 344x38 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (4,8) size 54x27
+                text run at (4,8) width 54: "TD M"
+            LayoutTableCell {TD} at (344,39) size 123x32 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (467,39) size 114x32 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (2,129) size 581x184
+          LayoutTableRow {TR} at (0,0) size 581x104
+            LayoutTableCell {TD} at (0,71) size 137x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (137,34) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (344,37) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (467,37) size 114x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,104) size 581x80
+            LayoutTableCell {TD} at (137,129) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (344,129) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (467,129) size 114x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {DIV} at (0,488.20) size 784x31
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,519.20) size 784x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-quirks-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-quirks-expected.png
new file mode 100644
index 0000000..fe0fa796
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-quirks-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-quirks-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-quirks-expected.txt
new file mode 100644
index 0000000..7816e42
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-quirks-expected.txt
@@ -0,0 +1,77 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 784x17
+        LayoutText {#text} at (0,0) size 342x17
+          text run at (0,0) width 342: "crbug.com/35679: Background on 'table'"
+      LayoutBlockFlow {P} at (0,32.20) size 784x16
+        LayoutText {#text} at (0,0) size 656x16
+          text run at (0,0) width 656: "There should be three aqua stripes just inside the bottom and right table borders."
+      LayoutTable {TABLE} at (0,61.20) size 626x463 [color=#FFFFFF] [bgcolor=#000000] [border: (5px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 626x27
+          LayoutText {#text} at (145,0) size 336x27
+            text run at (145,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (5,32) size 616x110
+          LayoutTableRow {TR} at (0,7) size 616x96
+            LayoutTableCell {TH} at (7,42) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,30) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,42) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,42) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TBODY} at (5,142) size 616x198
+          LayoutTableRow {TR} at (0,0) size 616x104
+            LayoutTableCell {TD} at (7,68) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,36) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,36) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,36) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,111) size 616x80
+            LayoutTableCell {TD} at (144,135) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,135) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,135) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+        LayoutTableSection {TFOOT} at (5,340) size 616x118
+          LayoutTableRow {TR} at (0,0) size 616x111
+            LayoutTableCell {TD} at (7,40) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,40) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,40) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+      LayoutBlockFlow {DIV} at (0,524.20) size 784x31
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,555.20) size 784x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-collapsed-border-expected.png
new file mode 100644
index 0000000..40fc98a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-collapsed-border-expected.txt
new file mode 100644
index 0000000..a52054dc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-collapsed-border-expected.txt
@@ -0,0 +1,92 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 793
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x793 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x793.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x770.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 378x17
+          text run at (0,0) width 378: "crbug.com/35679: Background on 'table-row'"
+      LayoutTable {TABLE} at (0,32.20) size 590x461 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 590x27
+          LayoutText {#text} at (129,0) size 332x27
+            text run at (129,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (2,33) size 585x105
+          LayoutTableRow {TR} at (0,0) size 585x105 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+            LayoutTableCell {TH} at (0,36) size 137x33 [border: (3px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (44,4) size 46x21
+                text run at (44,4) width 46: "TH A"
+            LayoutTableCell {TH} at (137,34) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (344,37) size 125x31 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,4) size 46x21
+                text run at (42,4) width 46: "TH C"
+            LayoutTableCell {TH} at (469,37) size 116x31 [border: (3px dashed #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (36,4) size 45x21
+                text run at (36,4) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (2,342) size 585x117
+          LayoutTableRow {TR} at (0,0) size 585x117
+            LayoutTableCell {TD} at (0,40) size 344x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (3,8) size 54x27
+                text run at (3,8) width 54: "TD M"
+            LayoutTableCell {TD} at (344,42) size 125x33 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,4) size 52x27
+                text run at (2,4) width 52: "TD O"
+            LayoutTableCell {TD} at (469,42) size 116x33 [border: (3px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,4) size 50x27
+                text run at (2,4) width 50: "TD P"
+        LayoutTableSection {TBODY} at (2,138) size 585x204
+          LayoutTableRow {TR} at (0,0) size 585x115 [bgcolor=#000000] [border: (9px dashed #FFFFFF)]
+            LayoutTableCell {TD} at (0,81) size 137x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (137,37) size 207x40 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (344,38) size 125x38 [border: (5px dashed #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 52x27
+                text run at (6,6) width 52: "TD G"
+            LayoutTableCell {TD} at (469,38) size 116x38 [border: (5px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 52x27
+                text run at (6,6) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 585x89 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+            LayoutTableCell {TD} at (137,141) size 207x36 [border: (5px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,6) size 48x27
+                text run at (8,6) width 48: "TD J"
+            LayoutTableCell {TD} at (344,141) size 125x36 [border: (5px dashed #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (4,6) size 52x27
+                text run at (4,6) width 52: "TD K"
+            LayoutTableCell {TD} at (469,141) size 116x36 [border: (5px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (4,6) size 48x27
+                text run at (4,6) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,506.20) size 769x16
+        LayoutText {#text} at (0,0) size 176x16
+          text run at (0,0) width 176: "Three rows are styled."
+      LayoutBlockFlow {P} at (0,535.20) size 769x64
+        LayoutText {#text} at (0,0) size 752x64
+          text run at (0,0) width 752: "The first row should have three aqua stripes just inside the bottom and right padding edges of"
+          text run at (0,16) width 728: "its last cell. The bottom three stripes should continue across the row, appearing along the"
+          text run at (0,32) width 728: "bottom of cells A, B, and C. (The bottom aqua stripe will be obscured by the thicker bottom"
+          text run at (0,48) width 144: "border in cell B.)"
+      LayoutBlockFlow {P} at (0,612.20) size 769x48
+        LayoutText {#text} at (0,0) size 768x48
+          text run at (0,0) width 736: "The second row should have three vertical aqua stripes a few pixels to the right of the left"
+          text run at (0,16) width 768: "padding edge. Three horizontal aqua stripes should cut across the first cell and align along the"
+          text run at (0,32) width 232: "bottom border edge of cell G."
+      LayoutBlockFlow {P} at (0,673.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 752: "The third row should have three horizontal aqua stripes along the top of the last three cells,"
+          text run at (0,16) width 672: "aligning along cell K's top padding edge. The stripes will not continue into cell E."
+      LayoutBlockFlow {DIV} at (0,718.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,753.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-expected.png
new file mode 100644
index 0000000..a570dfd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-expected.txt
new file mode 100644
index 0000000..673314c1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-expected.txt
@@ -0,0 +1,92 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 815
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x815 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x815.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x792.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 378x17
+          text run at (0,0) width 378: "crbug.com/35679: Background on 'table-row'"
+      LayoutTable {TABLE} at (0,32.20) size 630x483 [color=#FFFFFF] [border: (3px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 630x27
+          LayoutText {#text} at (147,0) size 336x27
+            text run at (147,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (3,30) size 624x122
+          LayoutTableRow {TR} at (0,7) size 624x108 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+            LayoutTableCell {TH} at (7,48) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,36) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,48) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 121x34 [border: (5px dashed #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (38,6) size 45x21
+                text run at (38,6) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (3,358) size 624x122
+          LayoutTableRow {TR} at (0,0) size 624x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 121x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (3,152) size 624x206
+          LayoutTableRow {TR} at (0,0) size 624x108 [bgcolor=#000000] [border: (9px dashed #FFFFFF)]
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,30) size 118x47 [border: (9px dashed #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (10,10) size 52x27
+                text run at (10,10) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 121x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 624x84 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,137) size 118x39 [border: (5px dashed #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 52x27
+                text run at (6,6) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 121x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,528.20) size 769x16
+        LayoutText {#text} at (0,0) size 176x16
+          text run at (0,0) width 176: "Three rows are styled."
+      LayoutBlockFlow {P} at (0,557.20) size 769x64
+        LayoutText {#text} at (0,0) size 752x64
+          text run at (0,0) width 752: "The first row should have three aqua stripes just inside the bottom and right padding edges of"
+          text run at (0,16) width 728: "its last cell. The bottom three stripes should continue across the row, appearing along the"
+          text run at (0,32) width 728: "bottom of cells A, B, and C. (The bottom aqua stripe will be obscured by the thicker bottom"
+          text run at (0,48) width 144: "border in cell B.)"
+      LayoutBlockFlow {P} at (0,634.20) size 769x48
+        LayoutText {#text} at (0,0) size 768x48
+          text run at (0,0) width 736: "The second row should have three vertical aqua stripes a few pixels to the right of the left"
+          text run at (0,16) width 768: "padding edge. Three horizontal aqua stripes should cut across the first cell and align along the"
+          text run at (0,32) width 232: "bottom border edge of cell G."
+      LayoutBlockFlow {P} at (0,695.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 752: "The third row should have three horizontal aqua stripes along the top of the last three cells,"
+          text run at (0,16) width 672: "aligning along cell K's top padding edge. The stripes will not continue into cell E."
+      LayoutBlockFlow {DIV} at (0,740.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,775.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
new file mode 100644
index 0000000..949a27b8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-group-collapsed-border-expected.txt
new file mode 100644
index 0000000..a83ffc4b7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-group-collapsed-border-expected.txt
@@ -0,0 +1,85 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 707
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x707 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x707.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x684.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 432x17
+          text run at (0,0) width 432: "crbug.com/35679: Background on 'table-row-group'"
+      LayoutTable {TABLE} at (0,32.20) size 590x449 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 590x27
+          LayoutText {#text} at (129,0) size 332x27
+            text run at (129,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (2,33) size 585x103 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableRow {TR} at (0,0) size 585x103
+            LayoutTableCell {TH} at (0,35) size 137x33 [border: (3px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (44,4) size 46x21
+                text run at (44,4) width 46: "TH A"
+            LayoutTableCell {TH} at (137,33) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (344,37) size 125x29 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,4) size 46x21
+                text run at (42,4) width 46: "TH C"
+            LayoutTableCell {TH} at (469,37) size 116x29 [border: (3px dashed #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (36,4) size 45x21
+                text run at (36,4) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (2,330) size 585x117
+          LayoutTableRow {TR} at (0,0) size 585x117
+            LayoutTableCell {TD} at (0,40) size 344x37 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (3,8) size 54x27
+                text run at (3,8) width 54: "TD M"
+            LayoutTableCell {TD} at (344,42) size 125x33 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,4) size 52x27
+                text run at (2,4) width 52: "TD O"
+            LayoutTableCell {TD} at (469,42) size 116x33 [border: (3px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,4) size 50x27
+                text run at (2,4) width 50: "TD P"
+        LayoutTableSection {TBODY} at (2,136) size 585x194 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableRow {TR} at (0,0) size 585x109
+            LayoutTableCell {TD} at (0,76) size 137x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (137,36) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (344,37) size 125x34 [border: (3px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,4) size 52x27
+                text run at (2,4) width 52: "TD G"
+            LayoutTableCell {TD} at (469,38) size 116x32 [border: (3px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,4) size 52x27
+                text run at (2,4) width 52: "TD H"
+          LayoutTableRow {TR} at (0,109) size 585x85
+            LayoutTableCell {TD} at (137,135) size 207x32 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (344,134) size 125x34 [border: (3px dashed #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (4,4) size 52x27
+                text run at (4,4) width 52: "TD K"
+            LayoutTableCell {TD} at (469,135) size 116x32 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (4,2) size 48x27
+                text run at (4,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,494.20) size 769x48
+        LayoutText {#text} at (0,0) size 760x48
+          text run at (0,0) width 744: "There should be three aqua stripes along the top of cells A, B, C, and D in the first row and"
+          text run at (0,16) width 760: "three stripes along the right edge of D, the last cell in that row. The stripes should align to"
+          text run at (0,32) width 336: "be just inside the padding edge of cell D."
+      LayoutBlockFlow {P} at (0,555.20) size 769x64
+        LayoutText {#text} at (0,0) size 768x64
+          text run at (0,0) width 752: "There should be three aqua stripes along the bottom of cells J, K, and L. The stripes continue"
+          text run at (0,16) width 744: "across the bottom of cell E, but are partially obscured by the border. The stripes turn up at"
+          text run at (0,32) width 768: "cell E's bottom left corner to run under its border a few pixels to the right of its left border"
+          text run at (0,48) width 600: "edge. The stripes will align to be just above cell K's bottom padding edge."
+      LayoutBlockFlow {DIV} at (0,632.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,667.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-group-expected.png
new file mode 100644
index 0000000..92affc75
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-group-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-group-expected.txt
new file mode 100644
index 0000000..aac1baf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_border-table-row-group-expected.txt
@@ -0,0 +1,85 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 741
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x741 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x741.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x718.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 432x17
+          text run at (0,0) width 432: "crbug.com/35679: Background on 'table-row-group'"
+      LayoutTable {TABLE} at (0,32.20) size 630x483 [color=#FFFFFF] [border: (3px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 630x27
+          LayoutText {#text} at (147,0) size 336x27
+            text run at (147,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (3,30) size 624x122 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableRow {TR} at (0,7) size 624x108
+            LayoutTableCell {TH} at (7,48) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,36) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,48) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 121x34 [border: (5px dashed #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (38,6) size 45x21
+                text run at (38,6) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (3,358) size 624x122
+          LayoutTableRow {TR} at (0,0) size 624x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 121x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (3,152) size 624x206 [bgcolor=#000000] [border: (5px dashed #FFFFFF)]
+          LayoutTableRow {TR} at (0,0) size 624x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 121x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 624x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,137) size 118x39 [border: (5px dashed #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (6,6) size 52x27
+                text run at (6,6) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 121x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,528.20) size 769x48
+        LayoutText {#text} at (0,0) size 760x48
+          text run at (0,0) width 744: "There should be three aqua stripes along the top of cells A, B, C, and D in the first row and"
+          text run at (0,16) width 760: "three stripes along the right edge of D, the last cell in that row. The stripes should align to"
+          text run at (0,32) width 336: "be just inside the padding edge of cell D."
+      LayoutBlockFlow {P} at (0,589.20) size 769x64
+        LayoutText {#text} at (0,0) size 768x64
+          text run at (0,0) width 752: "There should be three aqua stripes along the bottom of cells J, K, and L. The stripes continue"
+          text run at (0,16) width 744: "across the bottom of cell E, but are partially obscured by the border. The stripes turn up at"
+          text run at (0,32) width 768: "cell E's bottom left corner to run under its border a few pixels to the right of its left border"
+          text run at (0,48) width 600: "edge. The stripes will align to be just above cell K's bottom padding edge."
+      LayoutBlockFlow {DIV} at (0,666.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,701.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-hide-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-hide-collapsed-border-expected.png
new file mode 100644
index 0000000..1bf571235
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-hide-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-hide-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-hide-collapsed-border-expected.txt
new file mode 100644
index 0000000..cea321c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-hide-collapsed-border-expected.txt
@@ -0,0 +1,81 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 602
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x602 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x602.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x579.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 306x17
+          text run at (0,0) width 306: "crbug.com/35679: empty-cells: hide"
+      LayoutTable {TABLE} at (0,32.20) size 578x437 [color=#FFFFFF] [bgcolor=#0000FF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x27
+          LayoutText {#text} at (123,0) size 332x27
+            text run at (123,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,33) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,48) size 123x3 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,322) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,39) size 342x36 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 54x27
+                text run at (2,8) width 54: "TD M"
+            LayoutTableCell {TD} at (342,42) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (465,42) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (0,132) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,74) size 135x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (135,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (342,38) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (465,38) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,133) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (342,133) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (465,133) size 112x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,482.20) size 769x32
+        LayoutText {#text} at (0,0) size 392x16
+          text run at (0,0) width 392: "Both tables should look identical to the ones in "
+        LayoutInline {A} at (0,0) size 136x16 [color=#FFFF00]
+          LayoutText {#text} at (392,0) size 136x16
+            text run at (392,0) width 136: "empty-cells: show"
+        LayoutText {#text} at (528,0) size 768x32
+          text run at (528,0) width 240: " except that there should be a"
+          text run at (0,16) width 320: "blue blank where table cell C should be."
+      LayoutBlockFlow {DIV} at (0,527.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,562.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-hide-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-hide-expected.png
new file mode 100644
index 0000000..29ff4dd85
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-hide-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-hide-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-hide-expected.txt
new file mode 100644
index 0000000..0fb6eb19
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-hide-expected.txt
@@ -0,0 +1,81 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 636
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x636 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x636.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x613.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 306x17
+          text run at (0,0) width 306: "crbug.com/35679: empty-cells: hide"
+      LayoutTable {TABLE} at (0,32.20) size 618x471 [color=#FFFFFF] [bgcolor=#0000FF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x27
+          LayoutText {#text} at (141,0) size 336x27
+            text run at (141,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,28) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,55) size 118x4 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,348) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (1,142) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,516.20) size 769x32
+        LayoutText {#text} at (0,0) size 392x16
+          text run at (0,0) width 392: "Both tables should look identical to the ones in "
+        LayoutInline {A} at (0,0) size 136x16 [color=#FFFF00]
+          LayoutText {#text} at (392,0) size 136x16
+            text run at (392,0) width 136: "empty-cells: show"
+        LayoutText {#text} at (528,0) size 768x32
+          text run at (528,0) width 240: " except that there should be a"
+          text run at (0,16) width 320: "blue blank where table cell C should be."
+      LayoutBlockFlow {DIV} at (0,561.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,596.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-opacity-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-opacity-collapsed-border-expected.png
new file mode 100644
index 0000000..341a7f7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-opacity-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-opacity-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-opacity-collapsed-border-expected.txt
new file mode 100644
index 0000000..61cd858a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-opacity-collapsed-border-expected.txt
@@ -0,0 +1,103 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x350
+  LayoutBlockFlow {HTML} at (0,0) size 800x350.44
+    LayoutBlockFlow {BODY} at (8,18.72) size 784x323.72
+      LayoutBlockFlow {H3} at (0,0) size 784x22
+        LayoutText {#text} at (0,0) size 241x21
+          text run at (0,0) width 241: "crbug.com/35679: opacity: 0.5"
+      LayoutTable {TABLE} at (0,40.72) size 171x126 [bgcolor=#FFFFFF]
+        LayoutBlockFlow {CAPTION} at (0,0) size 171x36 [color=#FFFFFF]
+          LayoutText {#text} at (14,0) size 143x35
+            text run at (14,0) width 143: "With 'border-collapse:"
+            text run at (57,18) width 57: "collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,36) size 171x24
+        LayoutTableSection {TBODY} at (0,60) size 171x44
+      LayoutBlockFlow {UL} at (0,182.72) size 784x72
+        LayoutListItem {LI} at (40,0) size 744x18
+          LayoutListMarker (anonymous) at (-17,0) size 7x17: bullet
+          LayoutText {#text} at (0,0) size 220x17
+            text run at (0,0) width 220: "The first three rows should be red."
+        LayoutListItem {LI} at (40,18) size 744x18
+          LayoutListMarker (anonymous) at (-17,0) size 7x17: bullet
+          LayoutText {#text} at (0,0) size 198x17
+            text run at (0,0) width 198: "The last row should be orange."
+        LayoutListItem {LI} at (40,36) size 744x36
+          LayoutListMarker (anonymous) at (-17,0) size 7x17: bullet
+          LayoutText {#text} at (0,0) size 735x35
+            text run at (0,0) width 735: "Cell A should be purple. Cell P should also be purple, but of a shade that reflects the underlying orange rather than"
+            text run at (0,18) width 48: "the red."
+      LayoutBlockFlow {DIV} at (0,270.72) size 784x35
+        LayoutInline {A} at (0,0) size 88x17 [color=#0000EE]
+          LayoutBlockFlow {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,305.72) size 784x18
+        LayoutText {#text} at (0,0) size 606x17
+          text run at (0,0) width 606: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
+layer at (8,289) size 88x31 clip at (9,290) size 86x29 scrollHeight 56
+  LayoutBlockFlow {DIV} at (0,0) size 88x31 [border: (1px solid #C0C0C0)]
+    LayoutImage (floating) {IMG} at (2,2) size 16x16
+layer at (26,291) size 68x54 backgroundClip at (26,291) size 68x28 clip at (26,291) size 68x28
+  LayoutBlockFlow {DIV} at (18,2) size 68x54
+    LayoutText {#text} at (0,0) size 46x53
+      text run at (0,0) width 34: "Valid"
+      text run at (0,18) width 46: "HTML"
+      text run at (0,36) width 34: "4.01!"
+layer at (8,97) size 171x20 transparent
+  LayoutTableRow {TR} at (0,2) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TH} at (45,2) size 40x20 [r=0 c=1 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 38x17
+        text run at (1,1) width 38: "TH B"
+    LayoutTableCell {TH} at (87,11) size 39x2 [r=0 c=2 rs=1 cs=1]
+    LayoutTableCell {TH} at (128,2) size 41x20 [r=0 c=3 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 39x17
+        text run at (1,1) width 39: "TH D"
+layer at (10,97) size 41x20 transparent
+  LayoutTableCell {TH} at (2,2) size 41x20 [bgcolor=#0000FF] [r=0 c=0 rs=1 cs=1]
+    LayoutText {#text} at (1,1) size 39x17
+      text run at (1,1) width 39: "TH A"
+layer at (8,163) size 171x22 transparent
+  LayoutTableSection {TFOOT} at (0,104) size 171x22 [bgcolor=#FFFF00]
+layer at (8,163) size 171x20 transparent
+  LayoutTableRow {TR} at (0,0) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TD} at (2,0) size 83x20 [r=0 c=0 rs=1 cs=2]
+      LayoutText {#text} at (1,1) size 40x17
+        text run at (1,1) width 40: "TD M"
+    LayoutTableCell {TD} at (87,0) size 39x20 [r=0 c=2 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x17
+        text run at (1,1) width 37: "TD O"
+layer at (136,163) size 41x20 transparent
+  LayoutTableCell {TD} at (128,0) size 41x20 [bgcolor=#0000FF] [r=0 c=3 rs=1 cs=1]
+    LayoutText {#text} at (1,1) size 35x17
+      text run at (1,1) width 35: "TD P"
+layer at (8,119) size 171x20 transparent
+  LayoutTableRow {TR} at (0,0) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TD} at (2,11) size 41x20 [r=0 c=0 rs=2 cs=1]
+      LayoutText {#text} at (1,1) size 36x17
+        text run at (1,1) width 36: "TD E"
+    LayoutTableCell {TD} at (45,0) size 40x20 [r=0 c=1 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 35x17
+        text run at (1,1) width 35: "TD F"
+    LayoutTableCell {TD} at (87,0) size 39x20 [r=0 c=2 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x17
+        text run at (1,1) width 37: "TD G"
+    LayoutTableCell {TD} at (128,0) size 41x20 [r=0 c=3 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x17
+        text run at (1,1) width 37: "TD H"
+layer at (8,141) size 171x20 transparent
+  LayoutTableRow {TR} at (0,22) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TD} at (45,22) size 40x20 [r=1 c=1 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 32x17
+        text run at (1,1) width 32: "TD J"
+    LayoutTableCell {TD} at (87,22) size 39x20 [r=1 c=2 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x17
+        text run at (1,1) width 37: "TD K"
+    LayoutTableCell {TD} at (128,22) size 41x20 [r=1 c=3 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 36x17
+        text run at (1,1) width 36: "TD L"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-opacity-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-opacity-expected.png
new file mode 100644
index 0000000..341a7f7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-opacity-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-opacity-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-opacity-expected.txt
new file mode 100644
index 0000000..f58c3798
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-opacity-expected.txt
@@ -0,0 +1,103 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x350
+  LayoutBlockFlow {HTML} at (0,0) size 800x350.44
+    LayoutBlockFlow {BODY} at (8,18.72) size 784x323.72
+      LayoutBlockFlow {H3} at (0,0) size 784x22
+        LayoutText {#text} at (0,0) size 241x21
+          text run at (0,0) width 241: "crbug.com/35679: opacity: 0.5"
+      LayoutTable {TABLE} at (0,40.72) size 171x126 [bgcolor=#FFFFFF]
+        LayoutBlockFlow {CAPTION} at (0,0) size 171x36 [color=#FFFFFF]
+          LayoutText {#text} at (14,0) size 143x35
+            text run at (14,0) width 143: "With 'border-collapse:"
+            text run at (57,18) width 57: "separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,36) size 171x24
+        LayoutTableSection {TBODY} at (0,60) size 171x44
+      LayoutBlockFlow {UL} at (0,182.72) size 784x72
+        LayoutListItem {LI} at (40,0) size 744x18
+          LayoutListMarker (anonymous) at (-17,0) size 7x17: bullet
+          LayoutText {#text} at (0,0) size 220x17
+            text run at (0,0) width 220: "The first three rows should be red."
+        LayoutListItem {LI} at (40,18) size 744x18
+          LayoutListMarker (anonymous) at (-17,0) size 7x17: bullet
+          LayoutText {#text} at (0,0) size 198x17
+            text run at (0,0) width 198: "The last row should be orange."
+        LayoutListItem {LI} at (40,36) size 744x36
+          LayoutListMarker (anonymous) at (-17,0) size 7x17: bullet
+          LayoutText {#text} at (0,0) size 735x35
+            text run at (0,0) width 735: "Cell A should be purple. Cell P should also be purple, but of a shade that reflects the underlying orange rather than"
+            text run at (0,18) width 48: "the red."
+      LayoutBlockFlow {DIV} at (0,270.72) size 784x35
+        LayoutInline {A} at (0,0) size 88x17 [color=#0000EE]
+          LayoutBlockFlow {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,305.72) size 784x18
+        LayoutText {#text} at (0,0) size 606x17
+          text run at (0,0) width 606: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
+layer at (8,289) size 88x31 clip at (9,290) size 86x29 scrollHeight 56
+  LayoutBlockFlow {DIV} at (0,0) size 88x31 [border: (1px solid #C0C0C0)]
+    LayoutImage (floating) {IMG} at (2,2) size 16x16
+layer at (26,291) size 68x54 backgroundClip at (26,291) size 68x28 clip at (26,291) size 68x28
+  LayoutBlockFlow {DIV} at (18,2) size 68x54
+    LayoutText {#text} at (0,0) size 46x53
+      text run at (0,0) width 34: "Valid"
+      text run at (0,18) width 46: "HTML"
+      text run at (0,36) width 34: "4.01!"
+layer at (8,97) size 171x20 transparent
+  LayoutTableRow {TR} at (0,2) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TH} at (45,2) size 40x20 [r=0 c=1 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 38x17
+        text run at (1,1) width 38: "TH B"
+    LayoutTableCell {TH} at (87,11) size 39x2 [r=0 c=2 rs=1 cs=1]
+    LayoutTableCell {TH} at (128,2) size 41x20 [r=0 c=3 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 39x17
+        text run at (1,1) width 39: "TH D"
+layer at (10,97) size 41x20 transparent
+  LayoutTableCell {TH} at (2,2) size 41x20 [bgcolor=#0000FF] [r=0 c=0 rs=1 cs=1]
+    LayoutText {#text} at (1,1) size 39x17
+      text run at (1,1) width 39: "TH A"
+layer at (8,163) size 171x22 transparent
+  LayoutTableSection {TFOOT} at (0,104) size 171x22 [bgcolor=#FFFF00]
+layer at (8,163) size 171x20 transparent
+  LayoutTableRow {TR} at (0,0) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TD} at (2,0) size 83x20 [r=0 c=0 rs=1 cs=2]
+      LayoutText {#text} at (1,1) size 40x17
+        text run at (1,1) width 40: "TD M"
+    LayoutTableCell {TD} at (87,0) size 39x20 [r=0 c=2 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x17
+        text run at (1,1) width 37: "TD O"
+layer at (136,163) size 41x20 transparent
+  LayoutTableCell {TD} at (128,0) size 41x20 [bgcolor=#0000FF] [r=0 c=3 rs=1 cs=1]
+    LayoutText {#text} at (1,1) size 35x17
+      text run at (1,1) width 35: "TD P"
+layer at (8,119) size 171x20 transparent
+  LayoutTableRow {TR} at (0,0) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TD} at (2,11) size 41x20 [r=0 c=0 rs=2 cs=1]
+      LayoutText {#text} at (1,1) size 36x17
+        text run at (1,1) width 36: "TD E"
+    LayoutTableCell {TD} at (45,0) size 40x20 [r=0 c=1 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 35x17
+        text run at (1,1) width 35: "TD F"
+    LayoutTableCell {TD} at (87,0) size 39x20 [r=0 c=2 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x17
+        text run at (1,1) width 37: "TD G"
+    LayoutTableCell {TD} at (128,0) size 41x20 [r=0 c=3 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x17
+        text run at (1,1) width 37: "TD H"
+layer at (8,141) size 171x20 transparent
+  LayoutTableRow {TR} at (0,22) size 171x20 [bgcolor=#FF0000]
+    LayoutTableCell {TD} at (45,22) size 40x20 [r=1 c=1 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 32x17
+        text run at (1,1) width 32: "TD J"
+    LayoutTableCell {TD} at (87,22) size 39x20 [r=1 c=2 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 37x17
+        text run at (1,1) width 37: "TD K"
+    LayoutTableCell {TD} at (128,22) size 41x20 [r=1 c=3 rs=1 cs=1]
+      LayoutText {#text} at (1,1) size 36x17
+        text run at (1,1) width 36: "TD L"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-show-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-show-collapsed-border-expected.png
new file mode 100644
index 0000000..6ede2dcd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-show-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-show-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-show-expected.png
new file mode 100644
index 0000000..6d89b9a2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_layers-show-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-cell-collapsed-border-expected.png
new file mode 100644
index 0000000..fc92afa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-cell-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-cell-collapsed-border-expected.txt
new file mode 100644
index 0000000..581f33a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-cell-collapsed-border-expected.txt
@@ -0,0 +1,83 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 644
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x644 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x644.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x621.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 387x17
+          text run at (0,0) width 387: "crbug.com/35679: Background on 'table-cell'"
+      LayoutTable {TABLE} at (0,32.20) size 578x437 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x27
+          LayoutText {#text} at (123,0) size 332x27
+            text run at (123,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,33) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,322) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,39) size 342x36 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 54x27
+                text run at (2,8) width 54: "TD M"
+            LayoutTableCell {TD} at (342,42) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (465,42) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (0,132) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,74) size 135x42 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (135,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (342,38) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (465,38) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,133) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (342,133) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (465,133) size 112x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,482.20) size 769x16
+        LayoutText {#text} at (0,0) size 168x16
+          text run at (0,0) width 168: "Two cells are styled."
+      LayoutBlockFlow {P} at (0,511.20) size 769x16
+        LayoutText {#text} at (0,0) size 704x16
+          text run at (0,0) width 704: "There should be three aqua stripes just inside the top and left padding edges of cell E."
+      LayoutBlockFlow {P} at (0,540.20) size 769x16
+        LayoutText {#text} at (0,0) size 728x16
+          text run at (0,0) width 728: "There should be three aqua stripes just inside the bottom and right padding edges of Cell M"
+      LayoutBlockFlow {DIV} at (0,569.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,604.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-cell-expected.png
new file mode 100644
index 0000000..a41ec60
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-cell-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-cell-expected.txt
new file mode 100644
index 0000000..5d4ccdc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-cell-expected.txt
@@ -0,0 +1,83 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 678
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x678 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x678.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x655.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 387x17
+          text run at (0,0) width 387: "crbug.com/35679: Background on 'table-cell'"
+      LayoutTable {TABLE} at (0,32.20) size 618x471 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x27
+          LayoutText {#text} at (141,0) size 336x27
+            text run at (141,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,28) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,348) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (1,142) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [bgcolor=#000000] [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,516.20) size 769x16
+        LayoutText {#text} at (0,0) size 168x16
+          text run at (0,0) width 168: "Two cells are styled."
+      LayoutBlockFlow {P} at (0,545.20) size 769x16
+        LayoutText {#text} at (0,0) size 704x16
+          text run at (0,0) width 704: "There should be three aqua stripes just inside the top and left padding edges of cell E."
+      LayoutBlockFlow {P} at (0,574.20) size 769x16
+        LayoutText {#text} at (0,0) size 728x16
+          text run at (0,0) width 728: "There should be three aqua stripes just inside the bottom and right padding edges of Cell M"
+      LayoutBlockFlow {DIV} at (0,603.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,638.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-collapsed-border-expected.png
new file mode 100644
index 0000000..2851b84
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-collapsed-border-expected.txt
new file mode 100644
index 0000000..3914ca78
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-collapsed-border-expected.txt
@@ -0,0 +1,77 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x573
+  LayoutBlockFlow {HTML} at (0,0) size 800x573.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 784x550.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 784x17
+        LayoutText {#text} at (0,0) size 342x17
+          text run at (0,0) width 342: "crbug.com/35679: Background on 'table'"
+      LayoutBlockFlow {P} at (0,32.20) size 784x16
+        LayoutText {#text} at (0,0) size 632x16
+          text run at (0,0) width 632: "There should be three aqua stripes just inside the top and right table borders."
+      LayoutTable {TABLE} at (0,61.20) size 578x437 [color=#FFFFFF] [bgcolor=#000000] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x27
+          LayoutText {#text} at (123,0) size 332x27
+            text run at (123,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,33) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,322) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,39) size 342x36 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 54x27
+                text run at (2,8) width 54: "TD M"
+            LayoutTableCell {TD} at (342,42) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (465,42) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (0,132) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,74) size 135x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (135,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (342,38) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (465,38) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,133) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (342,133) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (465,133) size 112x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {DIV} at (0,498.20) size 784x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,533.20) size 784x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-collapsed-border-expected.png
new file mode 100644
index 0000000..6193efe4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-collapsed-border-expected.txt
new file mode 100644
index 0000000..72aed2fd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-collapsed-border-expected.txt
@@ -0,0 +1,87 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 708
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x708 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x708.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x685.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 405x17
+          text run at (0,0) width 405: "crbug.com/35679: Background on 'table-column'"
+      LayoutTable {TABLE} at (0,32.20) size 578x437 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x27
+          LayoutText {#text} at (123,0) size 332x27
+            text run at (123,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,33) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,322) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,39) size 342x36 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 54x27
+                text run at (2,8) width 54: "TD M"
+            LayoutTableCell {TD} at (342,42) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (465,42) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (0,132) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,74) size 135x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (135,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (342,38) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (465,38) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,133) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (342,133) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (465,133) size 112x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,482.20) size 769x16
+        LayoutText {#text} at (0,0) size 200x16
+          text run at (0,0) width 200: "Three columns are styled."
+      LayoutBlockFlow {P} at (0,511.20) size 769x64
+        LayoutText {#text} at (0,0) size 768x64
+          text run at (0,0) width 768: "In the first column, there should be three vertical stripes just inside the right border edge of"
+          text run at (0,16) width 744: "the first three cells. The stripes should continue in the last cell, turning a right angle to"
+          text run at (0,32) width 744: "the left into three aqua stripes along the bottom border edge of the last cell. The last cell"
+          text run at (0,48) width 536: "should not have three vertical stripes along its right border edge."
+      LayoutBlockFlow {P} at (0,588.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 752: "In the second column, there should be three vertical stripes just inside the right border edge"
+          text run at (0,16) width 200: "of the first three cells."
+      LayoutBlockFlow {DIV} at (0,633.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,668.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-expected.png
new file mode 100644
index 0000000..2e8a777
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-expected.txt
new file mode 100644
index 0000000..72212d9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-expected.txt
@@ -0,0 +1,91 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 787
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x787 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x787.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x764.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 405x17
+          text run at (0,0) width 405: "crbug.com/35679: Background on 'table-column'"
+      LayoutTable {TABLE} at (0,32.20) size 618x471 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x27
+          LayoutText {#text} at (141,0) size 336x27
+            text run at (141,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,28) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,348) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (1,142) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,516.20) size 769x16
+        LayoutText {#text} at (0,0) size 200x16
+          text run at (0,0) width 200: "Three columns are styled."
+      LayoutBlockFlow {P} at (0,545.20) size 769x64
+        LayoutText {#text} at (0,0) size 768x64
+          text run at (0,0) width 768: "In the first column, there should be three vertical stripes just inside the right border edge of"
+          text run at (0,16) width 744: "the first three cells. The stripes should continue in the last cell, turning a right angle to"
+          text run at (0,32) width 744: "the left into three aqua stripes along the bottom border edge of the last cell. The last cell"
+          text run at (0,48) width 536: "should not have three vertical stripes along its right border edge."
+      LayoutBlockFlow {P} at (0,622.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 752: "In the second column, there should be three vertical stripes just inside the right border edge"
+          text run at (0,16) width 200: "of the first three cells."
+      LayoutBlockFlow {P} at (0,667.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 752: "In the third column, there should be three vertical stripes just inside the top border edge of"
+          text run at (0,16) width 504: "the first cell and just inside the left edge of all four cells."
+      LayoutBlockFlow {DIV} at (0,712.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,747.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
new file mode 100644
index 0000000..1297abd8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-collapsed-border-expected.txt
new file mode 100644
index 0000000..92b3b68
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-collapsed-border-expected.txt
@@ -0,0 +1,79 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 647
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x647 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x647.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x624.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 459x17
+          text run at (0,0) width 459: "crbug.com/35679: Background on 'table-column-group'"
+      LayoutTable {TABLE} at (0,32.20) size 578x437 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x27
+          LayoutText {#text} at (123,0) size 332x27
+            text run at (123,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,33) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,322) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,39) size 465x36 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=3]
+              LayoutText {#text} at (2,8) size 54x27
+                text run at (2,8) width 54: "TD M"
+            LayoutTableCell {TD} at (465,42) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (0,132) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,74) size 135x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (135,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (342,38) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (465,38) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,133) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (342,133) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (465,133) size 112x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,482.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 752: "Three aqua stripes should run just inside the bottom border edge of the last cell in the first"
+          text run at (0,16) width 608: "three columns and up the right border edge of the cells in the third column."
+      LayoutBlockFlow {P} at (0,527.20) size 769x32
+        LayoutText {#text} at (0,0) size 768x32
+          text run at (0,0) width 768: "Three aqua stripes should also run just inside the top border edge of the first cell in the last"
+          text run at (0,16) width 520: "column and down the left border edge of each cell in that column."
+      LayoutBlockFlow {DIV} at (0,572.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,607.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-expected.png
new file mode 100644
index 0000000..955e047e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-expected.txt
new file mode 100644
index 0000000..07caa49
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-column-group-expected.txt
@@ -0,0 +1,82 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 681
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x681 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x681.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x658.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 459x17
+          text run at (0,0) width 459: "crbug.com/35679: Background on 'table-column-group'"
+      LayoutTable {TABLE} at (0,32.20) size 618x471 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x27
+          LayoutText {#text} at (141,0) size 336x27
+            text run at (141,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,28) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,348) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (1,142) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,516.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 752: "Three aqua stripes should run just inside the bottom border edge of the last cell in the first"
+          text run at (0,16) width 608: "three columns and up the right border edge of the cells in the third column."
+      LayoutBlockFlow {P} at (0,561.20) size 769x32
+        LayoutText {#text} at (0,0) size 768x32
+          text run at (0,0) width 768: "Three aqua stripes should also run just inside the top border edge of the first cell in the last"
+          text run at (0,16) width 520: "column and down the left border edge of each cell in that column."
+      LayoutBlockFlow {DIV} at (0,606.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,641.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-expected.png
new file mode 100644
index 0000000..c159087
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-expected.txt
new file mode 100644
index 0000000..1e72294
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-expected.txt
@@ -0,0 +1,77 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 607
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x607 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x607.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x584.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 342x17
+          text run at (0,0) width 342: "crbug.com/35679: Background on 'table'"
+      LayoutBlockFlow {P} at (0,32.20) size 769x16
+        LayoutText {#text} at (0,0) size 632x16
+          text run at (0,0) width 632: "There should be three aqua stripes just inside the top and right table borders."
+      LayoutTable {TABLE} at (0,61.20) size 618x471 [color=#FFFFFF] [bgcolor=#000000] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x27
+          LayoutText {#text} at (141,0) size 336x27
+            text run at (141,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,28) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TBODY} at (1,142) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+        LayoutTableSection {TFOOT} at (1,348) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+      LayoutBlockFlow {DIV} at (0,532.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,567.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-collapsed-border-expected.png
new file mode 100644
index 0000000..bed6dbd4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-collapsed-border-expected.txt
new file mode 100644
index 0000000..b02416e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-collapsed-border-expected.txt
@@ -0,0 +1,98 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 753
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x753 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x753.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x730.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 378x17
+          text run at (0,0) width 378: "crbug.com/35679: Background on 'table-row'"
+      LayoutTable {TABLE} at (0,32.20) size 578x437 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x27
+          LayoutText {#text} at (123,0) size 332x27
+            text run at (123,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,33) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99 [bgcolor=#000000]
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,322) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,39) size 342x36 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 54x27
+                text run at (2,8) width 54: "TD M"
+            LayoutTableCell {TD} at (342,42) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (465,42) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (0,132) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107 [bgcolor=#000000]
+            LayoutTableCell {TD} at (0,74) size 135x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (135,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (342,38) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (465,38) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83 [bgcolor=#000000]
+            LayoutTableCell {TD} at (135,133) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (342,133) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (465,133) size 112x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,482.20) size 769x16
+        LayoutText {#text} at (0,0) size 176x16
+          text run at (0,0) width 176: "Three rows are styled."
+      LayoutBlockFlow {P} at (0,511.20) size 769x48
+        LayoutText {#text} at (0,0) size 744x48
+          text run at (0,0) width 488: "The first row should have three aqua stripes just inside the "
+          text run at (488,0) width 256: "bottom and right border edges of"
+          text run at (0,16) width 256: "its last cell. The bottom three "
+          text run at (256,16) width 472: "stripes should continue across the row, appearing along the"
+          text run at (0,32) width 56: "border "
+          text run at (56,32) width 144: "edge of each cell."
+      LayoutBlockFlow {P} at (0,572.20) size 769x48
+        LayoutText {#text} at (0,0) size 752x48
+          text run at (0,0) width 480: "The second row should have three vertical aqua stripes just "
+          text run at (480,0) width 272: "inside the left border edge of the"
+          text run at (0,16) width 264: "top half of the first cell (Cell "
+          text run at (264,16) width 488: "E.) Three horizontal aqua stripes should cut across that cell"
+          text run at (0,32) width 32: "and "
+          text run at (32,32) width 472: "align along the bottom border edge of the last three cells."
+      LayoutBlockFlow {P} at (0,633.20) size 769x32
+        LayoutText {#text} at (0,0) size 744x32
+          text run at (0,0) width 528: "The third row should have three horizontal aqua stripes along the "
+          text run at (528,0) width 216: "top border edge of the last"
+          text run at (0,16) width 184: "three cells in the row."
+      LayoutBlockFlow {DIV} at (0,678.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,713.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-expected.png
new file mode 100644
index 0000000..342c393
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-expected.txt
new file mode 100644
index 0000000..6b6eee73
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-expected.txt
@@ -0,0 +1,98 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 787
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x787 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x787.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x764.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 225x17
+          text run at (0,0) width 225: "Background on 'table-row'"
+      LayoutTable {TABLE} at (0,32.20) size 618x471 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x27
+          LayoutText {#text} at (141,0) size 336x27
+            text run at (141,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,28) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100 [bgcolor=#000000]
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,348) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (1,142) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108 [bgcolor=#000000]
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84 [bgcolor=#000000]
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,516.20) size 769x16
+        LayoutText {#text} at (0,0) size 176x16
+          text run at (0,0) width 176: "Three rows are styled."
+      LayoutBlockFlow {P} at (0,545.20) size 769x48
+        LayoutText {#text} at (0,0) size 744x48
+          text run at (0,0) width 488: "The first row should have three aqua stripes just inside the "
+          text run at (488,0) width 256: "bottom and right border edges of"
+          text run at (0,16) width 256: "its last cell. The bottom three "
+          text run at (256,16) width 472: "stripes should continue across the row, appearing along the"
+          text run at (0,32) width 56: "border "
+          text run at (56,32) width 144: "edge of each cell."
+      LayoutBlockFlow {P} at (0,606.20) size 769x48
+        LayoutText {#text} at (0,0) size 752x48
+          text run at (0,0) width 480: "The second row should have three vertical aqua stripes just "
+          text run at (480,0) width 272: "inside the left border edge of the"
+          text run at (0,16) width 264: "top half of the first cell (Cell "
+          text run at (264,16) width 488: "E.) Three horizontal aqua stripes should cut across that cell"
+          text run at (0,32) width 32: "and "
+          text run at (32,32) width 472: "align along the bottom border edge of the last three cells."
+      LayoutBlockFlow {P} at (0,667.20) size 769x32
+        LayoutText {#text} at (0,0) size 744x32
+          text run at (0,0) width 528: "The third row should have three horizontal aqua stripes along the "
+          text run at (528,0) width 216: "top border edge of the last"
+          text run at (0,16) width 184: "three cells in the row."
+      LayoutBlockFlow {DIV} at (0,712.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,747.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
new file mode 100644
index 0000000..3726dfd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-group-collapsed-border-expected.txt
new file mode 100644
index 0000000..f1264e3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-group-collapsed-border-expected.txt
@@ -0,0 +1,82 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 647
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x647 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x647.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x624.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 432x17
+          text run at (0,0) width 432: "crbug.com/35679: Background on 'table-row-group'"
+      LayoutTable {TABLE} at (0,32.20) size 578x437 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x27
+          LayoutText {#text} at (123,0) size 332x27
+            text run at (123,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,33) size 577x99 [bgcolor=#000000]
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,322) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,39) size 342x36 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 54x27
+                text run at (2,8) width 54: "TD M"
+            LayoutTableCell {TD} at (342,42) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (465,42) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (0,132) size 577x190 [bgcolor=#000000]
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,74) size 135x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (135,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (342,38) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (465,38) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,133) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (342,133) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (465,133) size 112x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,482.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 752: "There should be three aqua stripes along the top border edge of each cell in the first row and"
+          text run at (0,16) width 568: "three stripes along the right border edge of the last cell in that row."
+      LayoutBlockFlow {P} at (0,527.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 752: "There should be three aqua stripes along the bottom border edge of cells E, J, K, and L. There"
+          text run at (0,16) width 584: "should also be three vertical aqua stripes along the left edge of cell E."
+      LayoutBlockFlow {DIV} at (0,572.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,607.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-group-expected.png
new file mode 100644
index 0000000..67e6bcf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-group-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-group-expected.txt
new file mode 100644
index 0000000..f0850ecc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_position-table-row-group-expected.txt
@@ -0,0 +1,82 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 681
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x681 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x681.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x658.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 432x17
+          text run at (0,0) width 432: "crbug.com/35679: Background on 'table-row-group'"
+      LayoutTable {TABLE} at (0,32.20) size 618x471 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x27
+          LayoutText {#text} at (141,0) size 336x27
+            text run at (141,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,28) size 616x114 [bgcolor=#000000]
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,348) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (1,142) size 616x206 [bgcolor=#000000]
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,516.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 752: "There should be three aqua stripes along the top border edge of each cell in the first row and"
+          text run at (0,16) width 568: "three stripes along the right border edge of the last cell in that row."
+      LayoutBlockFlow {P} at (0,561.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 752: "There should be three aqua stripes along the bottom border edge of cells E, J, K, and L. There"
+          text run at (0,16) width 584: "should also be three vertical aqua stripes along the left edge of cell E."
+      LayoutBlockFlow {DIV} at (0,606.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,641.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
new file mode 100644
index 0000000..f419e900
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-collapsed-border-expected.txt
new file mode 100644
index 0000000..f49a98cf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-collapsed-border-expected.txt
@@ -0,0 +1,86 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 647
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x647 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x647.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x624.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 387x17
+          text run at (0,0) width 387: "crbug.com/35679: Background on 'table-cell'"
+      LayoutTable {TABLE} at (0,32.20) size 578x437 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x27
+          LayoutText {#text} at (123,0) size 332x27
+            text run at (123,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,33) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,322) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,39) size 342x36 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 54x27
+                text run at (2,8) width 54: "TD M"
+            LayoutTableCell {TD} at (342,42) size 123x30 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (465,42) size 112x30 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (0,132) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,74) size 135x42 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (135,35) size 207x36 [bgcolor=#000000] [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (342,38) size 123x30 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (465,38) size 112x30 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,133) size 207x30 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (342,133) size 123x30 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (465,133) size 112x30 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,482.20) size 769x32
+        LayoutText {#text} at (0,0) size 760x32
+          text run at (0,0) width 392: "Each cell's background should fill the rectangle "
+          text run at (392,0) width 368: "defined by its border edge. There should be no"
+          text run at (0,16) width 136: "gaps or holes in "
+          text run at (136,16) width 232: "the background within a cell."
+      LayoutBlockFlow {P} at (0,527.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 320: "A purple band should align with the top "
+          text run at (320,0) width 432: "padding edge of each cell, and an orange stripe should"
+          text run at (0,16) width 64: "align a "
+          text run at (64,16) width 392: "few pixels to the left of its right padding edge."
+      LayoutBlockFlow {DIV} at (0,572.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,607.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-expected.png
new file mode 100644
index 0000000..eb1a90d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-expected.txt
new file mode 100644
index 0000000..370f018
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-expected.txt
@@ -0,0 +1,86 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 681
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x681 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x681.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x658.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 387x17
+          text run at (0,0) width 387: "crbug.com/35679: Background on 'table-cell'"
+      LayoutTable {TABLE} at (0,32.20) size 618x471 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x27
+          LayoutText {#text} at (141,0) size 336x27
+            text run at (141,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,28) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [bgcolor=#000000] [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,348) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (1,142) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [bgcolor=#000000] [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [bgcolor=#000000] [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,516.20) size 769x32
+        LayoutText {#text} at (0,0) size 760x32
+          text run at (0,0) width 392: "Each cell's background should fill the rectangle "
+          text run at (392,0) width 368: "defined by its border edge. There should be no"
+          text run at (0,16) width 136: "gaps or holes in "
+          text run at (136,16) width 232: "the background within a cell."
+      LayoutBlockFlow {P} at (0,561.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 320: "A purple band should align with the top "
+          text run at (320,0) width 432: "padding edge of each cell, and an orange stripe should"
+          text run at (0,16) width 64: "align a "
+          text run at (64,16) width 392: "few pixels to the left of its right padding edge."
+      LayoutBlockFlow {DIV} at (0,606.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,641.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-collapsed-border-expected.png
new file mode 100644
index 0000000..f5fdbb0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-collapsed-border-expected.txt
new file mode 100644
index 0000000..612d5903
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-collapsed-border-expected.txt
@@ -0,0 +1,87 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 647
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x647 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x647.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x624.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 342x17
+          text run at (0,0) width 342: "crbug.com/35679: Background on 'table'"
+      LayoutTable {TABLE} at (0,32.20) size 578x437 [color=#FFFFFF] [bgcolor=#000000] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x27
+          LayoutText {#text} at (123,0) size 332x27
+            text run at (123,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,33) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,322) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,39) size 342x36 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 54x27
+                text run at (2,8) width 54: "TD M"
+            LayoutTableCell {TD} at (342,42) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (465,42) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (0,132) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,74) size 135x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (135,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (342,38) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (465,38) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,133) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (342,133) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (465,133) size 112x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,482.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 376: "The table background should fill the rectangle "
+          text run at (376,0) width 376: "defined by the outer border of the table. There"
+          text run at (0,16) width 144: "should be no gaps "
+          text run at (144,16) width 456: "or holes in the background and the stripes should all be "
+          text run at (600,16) width 88: "continuous."
+      LayoutBlockFlow {P} at (0,527.20) size 769x32
+        LayoutText {#text} at (0,0) size 736x32
+          text run at (0,0) width 368: "A purple band should align with the left edge "
+          text run at (368,0) width 368: "of the painted area, and an aqua stripe should"
+          text run at (0,16) width 152: "align a few pixels "
+          text run at (152,16) width 168: "below the top border."
+      LayoutBlockFlow {DIV} at (0,572.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,607.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-collapsed-border-expected.png
new file mode 100644
index 0000000..c1e18c12
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-collapsed-border-expected.txt
new file mode 100644
index 0000000..c742526
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-collapsed-border-expected.txt
@@ -0,0 +1,96 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 724
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x724 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x724.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x701.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 405x17
+          text run at (0,0) width 405: "crbug.com/35679: Background on 'table-column'"
+      LayoutTable {TABLE} at (0,32.20) size 578x437 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x27
+          LayoutText {#text} at (123,0) size 332x27
+            text run at (123,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+        LayoutTableSection {THEAD} at (0,33) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,322) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,39) size 342x36 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 54x27
+                text run at (2,8) width 54: "TD M"
+            LayoutTableCell {TD} at (342,42) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (465,42) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (0,132) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,74) size 135x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (135,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (342,38) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (465,38) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,133) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (342,133) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (465,133) size 112x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,482.20) size 769x16
+        LayoutText {#text} at (0,0) size 224x16
+          text run at (0,0) width 224: "All four columns are styled."
+      LayoutBlockFlow {P} at (0,511.20) size 769x64
+        LayoutText {#text} at (0,0) size 768x64
+          text run at (0,0) width 424: "The table column background should be visible within "
+          text run at (424,0) width 344: "the border edge of each cell originating in"
+          text run at (0,16) width 160: "the column, and the "
+          text run at (160,16) width 520: "background should be continuously tiled to fill the entire cell. "
+          text run at (680,16) width 80: "Within the"
+          text run at (0,32) width 448: "column, all stripes should line up as if the cells were "
+          text run at (448,32) width 288: "cutouts in a stencil placed over the"
+          text run at (0,48) width 152: "column background. "
+          text run at (152,48) width 480: "Furthermore, horizontal stripes should align across columns."
+      LayoutBlockFlow {P} at (0,588.20) size 769x48
+        LayoutText {#text} at (0,0) size 752x48
+          text run at (0,0) width 320: "A red band should align with the bottom "
+          text run at (320,0) width 432: "border edge of the last cell in each column. An orange"
+          text run at (0,16) width 56: "stripe "
+          text run at (56,16) width 520: "should align a few pixels to the left of the right border of the "
+          text run at (576,16) width 152: "non-column-spanning"
+          text run at (0,32) width 168: "cells in each column."
+      LayoutBlockFlow {DIV} at (0,649.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,684.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-expected.png
new file mode 100644
index 0000000..dd397e0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-expected.txt
new file mode 100644
index 0000000..de2d2d1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-expected.txt
@@ -0,0 +1,96 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 758
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x758 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x758.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x735.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 405x17
+          text run at (0,0) width 405: "crbug.com/35679: Background on 'table-column'"
+      LayoutTable {TABLE} at (0,32.20) size 618x471 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x27
+          LayoutText {#text} at (141,0) size 336x27
+            text run at (141,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0 [bgcolor=#000000]
+        LayoutTableSection {THEAD} at (1,28) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,348) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (1,142) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,516.20) size 769x16
+        LayoutText {#text} at (0,0) size 224x16
+          text run at (0,0) width 224: "All four columns are styled."
+      LayoutBlockFlow {P} at (0,545.20) size 769x64
+        LayoutText {#text} at (0,0) size 768x64
+          text run at (0,0) width 424: "The table column background should be visible within "
+          text run at (424,0) width 344: "the border edge of each cell originating in"
+          text run at (0,16) width 160: "the column, and the "
+          text run at (160,16) width 520: "background should be continuously tiled to fill the entire cell. "
+          text run at (680,16) width 80: "Within the"
+          text run at (0,32) width 448: "column, all stripes should line up as if the cells were "
+          text run at (448,32) width 288: "cutouts in a stencil placed over the"
+          text run at (0,48) width 152: "column background. "
+          text run at (152,48) width 480: "Furthermore, horizontal stripes should align across columns."
+      LayoutBlockFlow {P} at (0,622.20) size 769x48
+        LayoutText {#text} at (0,0) size 752x48
+          text run at (0,0) width 320: "A red band should align with the bottom "
+          text run at (320,0) width 432: "border edge of the last cell in each column. An orange"
+          text run at (0,16) width 56: "stripe "
+          text run at (56,16) width 520: "should align a few pixels to the left of the right border of the "
+          text run at (576,16) width 152: "non-column-spanning"
+          text run at (0,32) width 168: "cells in each column."
+      LayoutBlockFlow {DIV} at (0,683.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,718.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
new file mode 100644
index 0000000..b081a904
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-collapsed-border-expected.txt
new file mode 100644
index 0000000..ed14d2f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-collapsed-border-expected.txt
@@ -0,0 +1,98 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 740
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x740 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x740.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x717.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 459x17
+          text run at (0,0) width 459: "crbug.com/35679: Background on 'table-column-group'"
+      LayoutTable {TABLE} at (0,32.20) size 578x437 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x27
+          LayoutText {#text} at (123,0) size 332x27
+            text run at (123,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,33) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,322) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,39) size 342x36 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 54x27
+                text run at (2,8) width 54: "TD M"
+            LayoutTableCell {TD} at (342,42) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (465,42) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (0,132) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,74) size 135x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (135,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (342,38) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (465,38) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,133) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (342,133) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (465,133) size 112x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,482.20) size 769x32
+        LayoutText {#text} at (0,0) size 760x32
+          text run at (0,0) width 360: "The first column group spans the first three "
+          text run at (360,0) width 400: "columns. The second column group only contains the"
+          text run at (0,16) width 96: "last column."
+      LayoutBlockFlow {P} at (0,527.20) size 769x64
+        LayoutText {#text} at (0,0) size 760x64
+          text run at (0,0) width 416: "The table column group background should be visible "
+          text run at (416,0) width 280: "within the border edge of each cell"
+          text run at (0,16) width 208: "originating in the column "
+          text run at (208,16) width 528: "group. Within each column group, all stripes should line up as if "
+          text run at (736,16) width 24: "the"
+          text run at (0,32) width 488: "cells were cutouts in a stencil placed over the column group "
+          text run at (488,32) width 224: "background. Furthermore, the"
+          text run at (0,48) width 296: "horizontal stripes should also align "
+          text run at (296,48) width 232: "across the two column groups."
+      LayoutBlockFlow {P} at (0,604.20) size 769x48
+        LayoutText {#text} at (0,0) size 736x48
+          text run at (0,0) width 376: "A purple band should align with the top border "
+          text run at (376,0) width 344: "edge of the cells in the first row. An aqua"
+          text run at (0,16) width 176: "stripe should align a "
+          text run at (176,16) width 512: "few pixels to the right of the left border edge of cells in the "
+          text run at (688,16) width 48: "column"
+          text run at (0,32) width 192: "group's leftmost column."
+      LayoutBlockFlow {DIV} at (0,665.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,700.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-expected.png
new file mode 100644
index 0000000..b0ceb8a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-expected.txt
new file mode 100644
index 0000000..e3e67e3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-expected.txt
@@ -0,0 +1,98 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 774
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x774 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x774.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x751.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 459x17
+          text run at (0,0) width 459: "crbug.com/35679: Background on 'table-column-group'"
+      LayoutTable {TABLE} at (0,32.20) size 618x471 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x27
+          LayoutText {#text} at (141,0) size 336x27
+            text run at (141,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0 [bgcolor=#000000]
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,28) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,348) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (1,142) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,516.20) size 769x32
+        LayoutText {#text} at (0,0) size 760x32
+          text run at (0,0) width 360: "The first column group spans the first three "
+          text run at (360,0) width 400: "columns. The second column group only contains the"
+          text run at (0,16) width 96: "last column."
+      LayoutBlockFlow {P} at (0,561.20) size 769x64
+        LayoutText {#text} at (0,0) size 760x64
+          text run at (0,0) width 416: "The table column group background should be visible "
+          text run at (416,0) width 280: "within the border edge of each cell"
+          text run at (0,16) width 208: "originating in the column "
+          text run at (208,16) width 528: "group. Within each column group, all stripes should line up as if "
+          text run at (736,16) width 24: "the"
+          text run at (0,32) width 488: "cells were cutouts in a stencil placed over the column group "
+          text run at (488,32) width 224: "background. Furthermore, the"
+          text run at (0,48) width 296: "horizontal stripes should also align "
+          text run at (296,48) width 232: "across the two column groups."
+      LayoutBlockFlow {P} at (0,638.20) size 769x48
+        LayoutText {#text} at (0,0) size 736x48
+          text run at (0,0) width 376: "A purple band should align with the top border "
+          text run at (376,0) width 344: "edge of the cells in the first row. An aqua"
+          text run at (0,16) width 176: "stripe should align a "
+          text run at (176,16) width 512: "few pixels to the right of the left border edge of cells in the "
+          text run at (688,16) width 48: "column"
+          text run at (0,32) width 192: "group's leftmost column."
+      LayoutBlockFlow {DIV} at (0,699.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,734.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-expected.png
new file mode 100644
index 0000000..9f76dcd4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-expected.txt
new file mode 100644
index 0000000..5ad0385
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-expected.txt
@@ -0,0 +1,87 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 681
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x681 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x681.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x658.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 342x17
+          text run at (0,0) width 342: "crbug.com/35679: Background on 'table'"
+      LayoutTable {TABLE} at (0,32.20) size 618x471 [color=#FFFFFF] [bgcolor=#000000] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x27
+          LayoutText {#text} at (141,0) size 336x27
+            text run at (141,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,28) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,348) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (1,142) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,516.20) size 769x32
+        LayoutText {#text} at (0,0) size 752x32
+          text run at (0,0) width 376: "The table background should fill the rectangle "
+          text run at (376,0) width 376: "defined by the outer border of the table. There"
+          text run at (0,16) width 144: "should be no gaps "
+          text run at (144,16) width 456: "or holes in the background and the stripes should all be "
+          text run at (600,16) width 88: "continuous."
+      LayoutBlockFlow {P} at (0,561.20) size 769x32
+        LayoutText {#text} at (0,0) size 736x32
+          text run at (0,0) width 368: "A purple band should align with the left edge "
+          text run at (368,0) width 368: "of the painted area, and an aqua stripe should"
+          text run at (0,16) width 152: "align a few pixels "
+          text run at (152,16) width 168: "below the top border."
+      LayoutBlockFlow {DIV} at (0,606.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,641.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-collapsed-border-expected.png
new file mode 100644
index 0000000..f3450fe
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-collapsed-border-expected.txt
new file mode 100644
index 0000000..4e22b6c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-collapsed-border-expected.txt
@@ -0,0 +1,96 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 724
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x724 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x724.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x701.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 378x17
+          text run at (0,0) width 378: "crbug.com/35679: Background on 'table-row'"
+      LayoutTable {TABLE} at (0,32.20) size 578x437 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x27
+          LayoutText {#text} at (123,0) size 332x27
+            text run at (123,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,33) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99 [bgcolor=#000000]
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,322) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114 [bgcolor=#000000]
+            LayoutTableCell {TD} at (0,39) size 342x36 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 54x27
+                text run at (2,8) width 54: "TD M"
+            LayoutTableCell {TD} at (342,42) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (465,42) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (0,132) size 577x190
+          LayoutTableRow {TR} at (0,0) size 577x107 [bgcolor=#000000]
+            LayoutTableCell {TD} at (0,74) size 135x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (135,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (342,38) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (465,38) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83 [bgcolor=#000000]
+            LayoutTableCell {TD} at (135,133) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (342,133) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (465,133) size 112x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,482.20) size 769x16
+        LayoutText {#text} at (0,0) size 200x16
+          text run at (0,0) width 200: "All four rows are styled."
+      LayoutBlockFlow {P} at (0,511.20) size 769x64
+        LayoutText {#text} at (0,0) size 744x64
+          text run at (0,0) width 400: "The table row background should be visible within "
+          text run at (400,0) width 344: "the border edge of each cell originating in"
+          text run at (0,16) width 136: "the row, and the "
+          text run at (136,16) width 520: "background should be continuously tiled to fill the entire cell. "
+          text run at (656,16) width 88: "Within each"
+          text run at (0,32) width 424: "row, all stripes should line up as if the cells were "
+          text run at (424,32) width 320: "cutouts in a stencil placed over the row"
+          text run at (0,48) width 200: "background. Furthermore, "
+          text run at (200,48) width 336: "vertical stripes should align across rows."
+      LayoutBlockFlow {P} at (0,588.20) size 769x48
+        LayoutText {#text} at (0,0) size 752x48
+          text run at (0,0) width 360: "A red band should align with the left border "
+          text run at (360,0) width 368: "edge of the first cells in each row. An orange"
+          text run at (0,16) width 160: "stripe should align "
+          text run at (160,16) width 536: "a few pixels above the bottom border of the non-row-spanning cells "
+          text run at (696,16) width 56: "in each"
+          text run at (0,32) width 32: "row."
+      LayoutBlockFlow {DIV} at (0,649.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,684.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-expected.png
new file mode 100644
index 0000000..e4c4769
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-expected.txt
new file mode 100644
index 0000000..7b6d38c8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-expected.txt
@@ -0,0 +1,96 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 758
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x758 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x758.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x735.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 378x17
+          text run at (0,0) width 378: "crbug.com/35679: Background on 'table-row'"
+      LayoutTable {TABLE} at (0,32.20) size 618x471 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x27
+          LayoutText {#text} at (141,0) size 336x27
+            text run at (141,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,28) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100 [bgcolor=#000000]
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,348) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115 [bgcolor=#000000]
+            LayoutTableCell {TD} at (7,42) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (1,142) size 616x206
+          LayoutTableRow {TR} at (0,0) size 616x108 [bgcolor=#000000]
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84 [bgcolor=#000000]
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,516.20) size 769x16
+        LayoutText {#text} at (0,0) size 200x16
+          text run at (0,0) width 200: "All four rows are styled."
+      LayoutBlockFlow {P} at (0,545.20) size 769x64
+        LayoutText {#text} at (0,0) size 744x64
+          text run at (0,0) width 400: "The table row background should be visible within "
+          text run at (400,0) width 344: "the border edge of each cell originating in"
+          text run at (0,16) width 136: "the row, and the "
+          text run at (136,16) width 520: "background should be continuously tiled to fill the entire cell. "
+          text run at (656,16) width 88: "Within each"
+          text run at (0,32) width 424: "row, all stripes should line up as if the cells were "
+          text run at (424,32) width 320: "cutouts in a stencil placed over the row"
+          text run at (0,48) width 200: "background. Furthermore, "
+          text run at (200,48) width 336: "vertical stripes should align across rows."
+      LayoutBlockFlow {P} at (0,622.20) size 769x48
+        LayoutText {#text} at (0,0) size 752x48
+          text run at (0,0) width 360: "A red band should align with the left border "
+          text run at (360,0) width 368: "edge of the first cells in each row. An orange"
+          text run at (0,16) width 160: "stripe should align "
+          text run at (160,16) width 536: "a few pixels above the bottom border of the non-row-spanning cells "
+          text run at (696,16) width 56: "in each"
+          text run at (0,32) width 32: "row."
+      LayoutBlockFlow {DIV} at (0,683.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,718.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
new file mode 100644
index 0000000..21990e5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-collapsed-border-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-collapsed-border-expected.txt
new file mode 100644
index 0000000..657dc9de
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-collapsed-border-expected.txt
@@ -0,0 +1,94 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 708
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x708 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x708.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x685.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 432x17
+          text run at (0,0) width 432: "crbug.com/35679: Background on 'table-row-group'"
+      LayoutTable {TABLE} at (0,32.20) size 578x437 [color=#FFFFFF] [border: (6px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 578x27
+          LayoutText {#text} at (123,0) size 332x27
+            text run at (123,0) width 332: "With 'border-collapse: collapse'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (0,33) size 577x99
+          LayoutTableRow {TR} at (0,0) size 577x99
+            LayoutTableCell {TH} at (0,34) size 135x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (135,31) size 207x37 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (81,8) size 46x21
+                text run at (81,8) width 46: "TH B"
+            LayoutTableCell {TH} at (342,37) size 123x25 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH C"
+            LayoutTableCell {TH} at (465,37) size 112x25 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (0,322) size 577x114
+          LayoutTableRow {TR} at (0,0) size 577x114
+            LayoutTableCell {TD} at (0,39) size 342x36 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,8) size 54x27
+                text run at (2,8) width 54: "TD M"
+            LayoutTableCell {TD} at (342,42) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (465,42) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (0,132) size 577x190 [bgcolor=#000000]
+          LayoutTableRow {TR} at (0,0) size 577x107
+            LayoutTableCell {TD} at (0,74) size 135x42 [border: (7px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (8,8) size 50x27
+                text run at (8,8) width 50: "TD E"
+            LayoutTableCell {TD} at (135,35) size 207x36 [border: (7px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,8) size 48x27
+                text run at (8,8) width 48: "TD F"
+            LayoutTableCell {TD} at (342,38) size 123x30 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (465,38) size 112x30 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,107) size 577x83
+            LayoutTableCell {TD} at (135,133) size 207x30 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (8,2) size 48x27
+                text run at (8,2) width 48: "TD J"
+            LayoutTableCell {TD} at (342,133) size 123x30 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (465,133) size 112x30 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,482.20) size 769x16
+        LayoutText {#text} at (0,0) size 424x16
+          text run at (0,0) width 384: "The styled row group spans the second and third "
+          text run at (384,0) width 40: "rows."
+      LayoutBlockFlow {P} at (0,511.20) size 769x48
+        LayoutText {#text} at (0,0) size 768x48
+          text run at (0,0) width 392: "The table row group background should be visible "
+          text run at (392,0) width 376: "within the border edge of each cell originating"
+          text run at (0,16) width 144: "in the row group. "
+          text run at (144,16) width 488: "All stripes should line up as if the cells were cutouts in a "
+          text run at (632,16) width 112: "stencil placed"
+          text run at (0,32) width 240: "over the row group background."
+      LayoutBlockFlow {P} at (0,572.20) size 769x48
+        LayoutText {#text} at (0,0) size 768x48
+          text run at (0,0) width 360: "A red band should align with the left border "
+          text run at (360,0) width 400: "edge of the first cells in each of the row group's"
+          text run at (0,16) width 128: "rows. An orange "
+          text run at (128,16) width 512: "stripe should align a few pixels above the bottom border of the "
+          text run at (640,16) width 128: "cells in the row"
+          text run at (0,32) width 136: "group's last row."
+      LayoutBlockFlow {DIV} at (0,633.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,668.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-expected.png
new file mode 100644
index 0000000..79d5e0f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-expected.txt
new file mode 100644
index 0000000..2078a55d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-expected.txt
@@ -0,0 +1,94 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 742
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x742 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
+  LayoutBlockFlow {HTML} at (0,0) size 785x742.41
+    LayoutBlockFlow {BODY} at (8,15.20) size 769x719.20 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H3} at (0,0) size 769x17
+        LayoutText {#text} at (0,0) size 432x17
+          text run at (0,0) width 432: "crbug.com/35679: Background on 'table-row-group'"
+      LayoutTable {TABLE} at (0,32.20) size 618x471 [color=#FFFFFF] [border: (1px dotted #FFFFFF)]
+        LayoutBlockFlow {CAPTION} at (0,0) size 618x27
+          LayoutText {#text} at (141,0) size 336x27
+            text run at (141,0) width 336: "With 'border-collapse: separate'"
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableCol {COLGROUP} at (0,0) size 0x0
+          LayoutTableCol {COL} at (0,0) size 0x0
+        LayoutTableSection {THEAD} at (1,28) size 616x114
+          LayoutTableRow {TR} at (0,7) size 616x100
+            LayoutTableCell {TH} at (7,44) size 130x26 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (42,2) size 46x21
+                text run at (42,2) width 46: "TH A"
+            LayoutTableCell {TH} at (144,32) size 220x50 [border: (13px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (87,14) size 46x21
+                text run at (87,14) width 46: "TH B"
+            LayoutTableCell {TH} at (371,44) size 118x26 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (36,2) size 46x21
+                text run at (36,2) width 46: "TH C"
+            LayoutTableCell {TH} at (496,44) size 113x26 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (34,2) size 45x21
+                text run at (34,2) width 45: "TH D"
+        LayoutTableSection {TFOOT} at (1,348) size 616x122
+          LayoutTableRow {TR} at (0,0) size 616x115
+            LayoutTableCell {TD} at (7,42) size 357x31 [border: (1px dotted #FFFFFF)] [r=0 c=0 rs=1 cs=2]
+              LayoutText {#text} at (2,2) size 54x27
+                text run at (2,2) width 54: "TD M"
+            LayoutTableCell {TD} at (371,42) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD O"
+            LayoutTableCell {TD} at (496,42) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 50x27
+                text run at (2,2) width 50: "TD P"
+        LayoutTableSection {TBODY} at (1,142) size 616x206 [bgcolor=#000000]
+          LayoutTableRow {TR} at (0,0) size 616x108
+            LayoutTableCell {TD} at (7,72) size 130x55 [border: (13px dotted #FFFFFF)] [r=0 c=0 rs=2 cs=1]
+              LayoutText {#text} at (14,14) size 50x27
+                text run at (14,14) width 50: "TD E"
+            LayoutTableCell {TD} at (144,38) size 220x31 [border: (1px dotted #FFFFFF)] [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD F"
+            LayoutTableCell {TD} at (371,38) size 118x31 [border: (1px dotted #FFFFFF)] [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD G"
+            LayoutTableCell {TD} at (496,38) size 113x31 [border: (1px dotted #FFFFFF)] [r=0 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD H"
+          LayoutTableRow {TR} at (0,115) size 616x84
+            LayoutTableCell {TD} at (144,141) size 220x31 [border: (1px dotted #FFFFFF)] [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD J"
+            LayoutTableCell {TD} at (371,141) size 118x31 [border: (1px dotted #FFFFFF)] [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 52x27
+                text run at (2,2) width 52: "TD K"
+            LayoutTableCell {TD} at (496,141) size 113x31 [border: (1px dotted #FFFFFF)] [r=1 c=3 rs=1 cs=1]
+              LayoutText {#text} at (2,2) size 48x27
+                text run at (2,2) width 48: "TD L"
+      LayoutBlockFlow {P} at (0,516.20) size 769x16
+        LayoutText {#text} at (0,0) size 424x16
+          text run at (0,0) width 384: "The styled row group spans the second and third "
+          text run at (384,0) width 40: "rows."
+      LayoutBlockFlow {P} at (0,545.20) size 769x48
+        LayoutText {#text} at (0,0) size 768x48
+          text run at (0,0) width 392: "The table row group background should be visible "
+          text run at (392,0) width 376: "within the border edge of each cell originating"
+          text run at (0,16) width 144: "in the row group. "
+          text run at (144,16) width 488: "All stripes should line up as if the cells were cutouts in a "
+          text run at (632,16) width 112: "stencil placed"
+          text run at (0,32) width 240: "over the row group background."
+      LayoutBlockFlow {P} at (0,606.20) size 769x48
+        LayoutText {#text} at (0,0) size 768x48
+          text run at (0,0) width 360: "A red band should align with the left border "
+          text run at (360,0) width 400: "edge of the first cells in each of the row group's"
+          text run at (0,16) width 128: "rows. An orange "
+          text run at (128,16) width 512: "stripe should align a few pixels above the bottom border of the "
+          text run at (640,16) width 128: "cells in the row"
+          text run at (0,32) width 136: "group's last row."
+      LayoutBlockFlow {DIV} at (0,667.20) size 769x35
+        LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
+          LayoutImage {IMG} at (0,0) size 88x31
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {ADDRESS} at (0,702.20) size 769x17
+        LayoutText {#text} at (0,0) size 704x17
+          text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/tbody-background-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/tbody-background-image-expected.png
new file mode 100644
index 0000000..9c4011f5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/tbody-background-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/tbody-background-image-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/table/tbody-background-image-expected.txt
new file mode 100644
index 0000000..910969e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/tbody-background-image-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x462
+  LayoutBlockFlow {HTML} at (0,0) size 800x462
+    LayoutBlockFlow {BODY} at (8,16) size 784x438
+      LayoutBlockFlow {P} at (0,0) size 784x18
+        LayoutText {#text} at (0,0) size 394x17
+          text run at (0,0) width 394: "crbug.com/35697: The image should be tiled across the table."
+      LayoutTable {TABLE} at (0,34) size 784x404
+        LayoutTableSection {TBODY} at (0,0) size 784x404
+          LayoutTableRow {TR} at (0,0) size 784x202
+            LayoutTableCell {TD} at (0,100) size 392x2 [r=0 c=0 rs=1 cs=1]
+            LayoutTableCell {TD} at (392,100) size 392x2 [r=0 c=1 rs=1 cs=1]
+          LayoutTableRow {TR} at (0,202) size 784x202
+            LayoutTableCell {TD} at (0,302) size 392x2 [r=1 c=0 rs=1 cs=1]
+            LayoutTableCell {TD} at (392,302) size 392x2 [r=1 c=1 rs=1 cs=1]
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index 8ccd128..4e999489 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.txt b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.txt
index 7ab2e29..3349b10 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.txt
@@ -1,41 +1,41 @@
-layer at (0,0) size 800x600 scrollWidth 1544 scrollHeight 1707
+layer at (0,0) size 800x600 clip at (0,0) size 785x585 scrollWidth 1544 scrollHeight 1707
   LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x1707 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x1707.19
-    LayoutBlockFlow {BODY} at (8,17.41) size 784x1676.78 [color=#00FF00] [bgcolor=#333333]
-      LayoutBlockFlow {H1} at (0,0) size 784x30
+layer at (0,0) size 785x1707 backgroundClip at (0,0) size 785x585 clip at (0,0) size 785x585
+  LayoutBlockFlow {HTML} at (0,0) size 785x1707.19
+    LayoutBlockFlow {BODY} at (8,17.41) size 769x1676.78 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H1} at (0,0) size 769x30
         LayoutText {#text} at (0,0) size 515x30
           text run at (0,0) width 515: "CSS2 Table Backgrounds Test Suite"
-      LayoutBlockFlow {H2} at (0,47.41) size 784x22
+      LayoutBlockFlow {H2} at (0,47.41) size 769x22
         LayoutText {#text} at (0,0) size 246x22
           text run at (0,0) width 246: "Part E: Special Tests"
-      LayoutBlockFlow {H3} at (0,85.58) size 784x17
+      LayoutBlockFlow {H3} at (0,85.58) size 769x17
         LayoutText {#text} at (0,0) size 153x17
           text run at (0,0) width 153: "Fixed Backgrounds"
-      LayoutBlockFlow {UL} at (0,117.78) size 784x64
-        LayoutListItem {LI} at (40,0) size 744x48
+      LayoutBlockFlow {UL} at (0,117.78) size 769x64
+        LayoutListItem {LI} at (40,0) size 729x48
           LayoutListMarker (anonymous) at (-16,0) size 6x16: bullet
-          LayoutText {#text} at (0,0) size 736x48
+          LayoutText {#text} at (0,0) size 704x48
             text run at (0,0) width 704: "If you scroll the table over the top left corner of the viewport, the first, second, and"
-            text run at (0,16) width 736: "fourth rows as well as cell L should reveal a purple and aqua band forming a 90-degree angle"
-            text run at (0,32) width 184: "in the top left corner."
-        LayoutListItem {LI} at (40,48) size 744x16
+            text run at (0,16) width 688: "fourth rows as well as cell L should reveal a purple and aqua band forming a 90-degree"
+            text run at (0,32) width 232: "angle in the top left corner."
+        LayoutListItem {LI} at (40,48) size 729x16
           LayoutListMarker (anonymous) at (-16,0) size 6x16: bullet
           LayoutText {#text} at (0,0) size 664x16
             text run at (0,0) width 664: "Cells A and P should have a rainbow background that seems attached to the viewport."
-      LayoutBlockFlow {DL} at (0,194.78) size 784x64
-        LayoutBlockFlow {DT} at (0,0) size 784x16
+      LayoutBlockFlow {DL} at (0,194.78) size 769x64
+        LayoutBlockFlow {DT} at (0,0) size 769x16
           LayoutText {#text} at (0,0) size 64x16
             text run at (0,0) width 64: "previous"
-        LayoutBlockFlow {DD} at (40,16) size 744x16
+        LayoutBlockFlow {DD} at (40,16) size 729x16
           LayoutInline {A} at (0,0) size 176x16 [color=#FFFF00]
             LayoutText {#text} at (0,0) size 176x16
               text run at (0,0) width 176: "Special Tests: opacity"
           LayoutText {#text} at (0,0) size 0x0
-        LayoutBlockFlow {DT} at (0,32) size 784x16
+        LayoutBlockFlow {DT} at (0,32) size 769x16
           LayoutText {#text} at (0,0) size 64x16
             text run at (0,0) width 64: "contents"
-        LayoutBlockFlow {DD} at (40,48) size 744x16
+        LayoutBlockFlow {DD} at (40,48) size 729x16
           LayoutInline {A} at (0,0) size 136x16 [color=#FFFF00]
             LayoutText {#text} at (0,0) size 136x16
               text run at (0,0) width 136: "Table of Contents"
@@ -154,14 +154,14 @@
             LayoutTableCell {TD} at (465,133) size 112x30 [border: (1px dotted #000000)] [r=1 c=3 rs=1 cs=1]
               LayoutText {#text} at (2,2) size 48x27
                 text run at (2,2) width 48: "TD L"
-      LayoutBlockFlow {DIV} at (0,1179.78) size 784x35
+      LayoutBlockFlow {DIV} at (0,1179.78) size 769x35
         LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
           LayoutImage {IMG} at (0,0) size 88x31
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {ADDRESS} at (0,1214.78) size 784x17
+      LayoutBlockFlow {ADDRESS} at (0,1214.78) size 769x17
         LayoutText {#text} at (0,0) size 704x17
           text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
-      LayoutBlockFlow {PRE} at (0,1244.78) size 784x432
+      LayoutBlockFlow {PRE} at (0,1244.78) size 769x432
         LayoutText {#text} at (0,0) size 1536x432
           text run at (0,0) width 1536: "................................................................................................................................................................................................"
           text run at (1536,0) width 0: " "
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png
index 2560a35..0beb98e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-pattern-no-repeat-with-transformations-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index a3528d1..68569c33 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.txt
index 130f18f..60c55909 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.txt
@@ -1,41 +1,41 @@
-layer at (0,0) size 800x600 scrollWidth 1544 scrollHeight 1707
+layer at (0,0) size 800x600 clip at (0,0) size 785x585 scrollWidth 1544 scrollHeight 1707
   LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x1707 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x1707.19
-    LayoutBlockFlow {BODY} at (8,17.41) size 784x1676.78 [color=#00FF00] [bgcolor=#333333]
-      LayoutBlockFlow {H1} at (0,0) size 784x30
+layer at (0,0) size 785x1707 backgroundClip at (0,0) size 785x585 clip at (0,0) size 785x585
+  LayoutBlockFlow {HTML} at (0,0) size 785x1707.19
+    LayoutBlockFlow {BODY} at (8,17.41) size 769x1676.78 [color=#00FF00] [bgcolor=#333333]
+      LayoutBlockFlow {H1} at (0,0) size 769x30
         LayoutText {#text} at (0,0) size 515x30
           text run at (0,0) width 515: "CSS2 Table Backgrounds Test Suite"
-      LayoutBlockFlow {H2} at (0,47.41) size 784x22
+      LayoutBlockFlow {H2} at (0,47.41) size 769x22
         LayoutText {#text} at (0,0) size 246x22
           text run at (0,0) width 246: "Part E: Special Tests"
-      LayoutBlockFlow {H3} at (0,85.58) size 784x17
+      LayoutBlockFlow {H3} at (0,85.58) size 769x17
         LayoutText {#text} at (0,0) size 153x17
           text run at (0,0) width 153: "Fixed Backgrounds"
-      LayoutBlockFlow {UL} at (0,117.78) size 784x64
-        LayoutListItem {LI} at (40,0) size 744x48
+      LayoutBlockFlow {UL} at (0,117.78) size 769x64
+        LayoutListItem {LI} at (40,0) size 729x48
           LayoutListMarker (anonymous) at (-16,0) size 6x16: bullet
-          LayoutText {#text} at (0,0) size 736x48
+          LayoutText {#text} at (0,0) size 704x48
             text run at (0,0) width 704: "If you scroll the table over the top left corner of the viewport, the first, second, and"
-            text run at (0,16) width 736: "fourth rows as well as cell L should reveal a purple and aqua band forming a 90-degree angle"
-            text run at (0,32) width 184: "in the top left corner."
-        LayoutListItem {LI} at (40,48) size 744x16
+            text run at (0,16) width 688: "fourth rows as well as cell L should reveal a purple and aqua band forming a 90-degree"
+            text run at (0,32) width 232: "angle in the top left corner."
+        LayoutListItem {LI} at (40,48) size 729x16
           LayoutListMarker (anonymous) at (-16,0) size 6x16: bullet
           LayoutText {#text} at (0,0) size 664x16
             text run at (0,0) width 664: "Cells A and P should have a rainbow background that seems attached to the viewport."
-      LayoutBlockFlow {DL} at (0,194.78) size 784x64
-        LayoutBlockFlow {DT} at (0,0) size 784x16
+      LayoutBlockFlow {DL} at (0,194.78) size 769x64
+        LayoutBlockFlow {DT} at (0,0) size 769x16
           LayoutText {#text} at (0,0) size 64x16
             text run at (0,0) width 64: "previous"
-        LayoutBlockFlow {DD} at (40,16) size 744x16
+        LayoutBlockFlow {DD} at (40,16) size 729x16
           LayoutInline {A} at (0,0) size 176x16 [color=#FFFF00]
             LayoutText {#text} at (0,0) size 176x16
               text run at (0,0) width 176: "Special Tests: opacity"
           LayoutText {#text} at (0,0) size 0x0
-        LayoutBlockFlow {DT} at (0,32) size 784x16
+        LayoutBlockFlow {DT} at (0,32) size 769x16
           LayoutText {#text} at (0,0) size 64x16
             text run at (0,0) width 64: "contents"
-        LayoutBlockFlow {DD} at (40,48) size 744x16
+        LayoutBlockFlow {DD} at (40,48) size 729x16
           LayoutInline {A} at (0,0) size 136x16 [color=#FFFF00]
             LayoutText {#text} at (0,0) size 136x16
               text run at (0,0) width 136: "Table of Contents"
@@ -154,14 +154,14 @@
             LayoutTableCell {TD} at (465,133) size 112x30 [border: (1px dotted #000000)] [r=1 c=3 rs=1 cs=1]
               LayoutText {#text} at (2,2) size 48x27
                 text run at (2,2) width 48: "TD L"
-      LayoutBlockFlow {DIV} at (0,1179.78) size 784x35
+      LayoutBlockFlow {DIV} at (0,1179.78) size 769x35
         LayoutInline {A} at (0,0) size 88x16 [color=#FFFF00]
           LayoutImage {IMG} at (0,0) size 88x31
         LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow {ADDRESS} at (0,1214.78) size 784x17
+      LayoutBlockFlow {ADDRESS} at (0,1214.78) size 769x17
         LayoutText {#text} at (0,0) size 704x17
           text run at (0,0) width 704: "CSS2 Table Backgrounds Test Suite designed and written by fantasai <fantasai@escape.com>"
-      LayoutBlockFlow {PRE} at (0,1244.78) size 784x432
+      LayoutBlockFlow {PRE} at (0,1244.78) size 769x432
         LayoutText {#text} at (0,0) size 1536x432
           text run at (0,0) width 1536: "................................................................................................................................................................................................"
           text run at (1536,0) width 0: " "
diff --git a/third_party/WebKit/LayoutTests/presentation/presentation-api.html b/third_party/WebKit/LayoutTests/presentation/presentation-api.html
index cc74cad..ff0514cd 100644
--- a/third_party/WebKit/LayoutTests/presentation/presentation-api.html
+++ b/third_party/WebKit/LayoutTests/presentation/presentation-api.html
@@ -22,7 +22,7 @@
 }, "Test that navigator.presentation is not an EventTarget.");
 
 test(function() {
-  var request = new PresentationRequest('http://foo.html');
+  const request = new PresentationRequest('http://foo.html');
   assert_equals(typeof(request.start), "function");
   assert_equals(typeof(request.reconnect), "function");
   assert_equals(typeof(request.getAvailability), "function");
@@ -32,7 +32,8 @@
 }, "Test PresentationRequest API types for a single URL.");
 
 test(function() {
-  var request = new PresentationRequest(["http://example.com", "cast://google.com/app_id=deadbeef"]);
+  const request = new PresentationRequest(
+      ["http://example.com", "cast://google.com/app_id=deadbeef"]);
   assert_equals(typeof(request.start), "function");
   assert_equals(typeof(request.reconnect), "function");
   assert_equals(typeof(request.getAvailability), "function");
diff --git a/third_party/WebKit/LayoutTests/presentation/presentation-close-reconnect.html b/third_party/WebKit/LayoutTests/presentation/presentation-close-reconnect.html
new file mode 100644
index 0000000..4c60a85
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/presentation/presentation-close-reconnect.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script src="../resources/mojo-helpers.js"></script>
+<script src="resources/presentation-service-mock.js"></script>
+<button>click me</button>
+<script>
+
+async_test(t => {
+  presentationServiceMock.then(mockService => {
+    const button = document.querySelector('button');
+    let connection = null;
+    const request = new PresentationRequest('https://example.com');
+
+    waitForClick(_ => {
+      request.start().then(conn => {
+        connection = conn;
+        assert_not_equals(connection, null);
+        assert_equals(connection.state, 'connecting');
+
+        connection.onclose = (_ => {
+          assert_equals(connection.state, 'closed');
+          request.reconnect(connection.id).then(
+            t.step_func_done(conn => {
+              assert_equals(connection, conn);
+              assert_equals(connection.state, 'connecting');
+            })
+          );
+        });
+        connection.close();
+      });
+    }, button);
+  });
+}, "Test that Presentation.reconnect() resolves with a previously closed presentation connection, whose state is updated to 'connecting.'");
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/presentation/presentation-navigation.html b/third_party/WebKit/LayoutTests/presentation/presentation-navigation.html
index ba5e230..cc921ff8 100644
--- a/third_party/WebKit/LayoutTests/presentation/presentation-navigation.html
+++ b/third_party/WebKit/LayoutTests/presentation/presentation-navigation.html
@@ -6,16 +6,17 @@
 <iframe></iframe>
 <script>
 
-var iframe = document.querySelector('iframe');
+const iframe = document.querySelector('iframe');
 
 async_test(t => {
   iframe.onload = t.step_func(() => {
-    var presentation = iframe.contentWindow.navigator.presentation;
+    const presentation = iframe.contentWindow.navigator.presentation;
     if (iframe.src.endsWith('#after-reload')) {
       assert_equals(presentation.defaultRequest, null);
       t.done();
     } else {
-      presentation.defaultRequest = new PresentationRequest("https://example.org");
+      presentation.defaultRequest =
+          new PresentationRequest("https://example.org");
       assert_not_equals(presentation.defaultRequest, null);
 
       iframe.src += '#after-reload';
diff --git a/third_party/WebKit/LayoutTests/presentation/presentation-reconnect.html b/third_party/WebKit/LayoutTests/presentation/presentation-reconnect.html
index 6d70f89..cf5699b9 100644
--- a/third_party/WebKit/LayoutTests/presentation/presentation-reconnect.html
+++ b/third_party/WebKit/LayoutTests/presentation/presentation-reconnect.html
@@ -3,7 +3,6 @@
 <body>
 <script src="../resources/testharness.js"></script>
 <script src="../resources/testharnessreport.js"></script>
-<script src="../resources/gc.js"></script>
 <script src="../resources/mojo-helpers.js"></script>
 <script src="resources/presentation-service-mock.js"></script>
 <button>click me</button>
@@ -11,9 +10,9 @@
 
 async_test(t => {
   presentationServiceMock.then(mockService => {
-    var button = document.querySelector('button');
-    var connection = null;
-    var request = new PresentationRequest('https://example.com');
+    const button = document.querySelector('button');
+    let connection = null;
+    const request = new PresentationRequest('https://example.com');
 
     waitForClick(_ => {
       request.start().then(conn => {
diff --git a/third_party/WebKit/LayoutTests/presentation/presentationconnectionavailableevent-ctor-mock.html b/third_party/WebKit/LayoutTests/presentation/presentationconnectionavailableevent-ctor-mock.html
index 85b752dd..f8d8dc8 100644
--- a/third_party/WebKit/LayoutTests/presentation/presentationconnectionavailableevent-ctor-mock.html
+++ b/third_party/WebKit/LayoutTests/presentation/presentationconnectionavailableevent-ctor-mock.html
@@ -10,12 +10,12 @@
 
 async_test(t => {
   presentationServiceMock.then(t.step_func(mockService => {
-    var button = document.querySelector('button');
+    const button = document.querySelector('button');
     // This is receiving the user gesture and runs the callback.
     waitForClick(t.step_func(_ => {
       new PresentationRequest('https://example.com').start().then(
       t.step_func_done(result => {
-        var e = new PresentationConnectionAvailableEvent(
+        const e = new PresentationConnectionAvailableEvent(
             'connectionavailable', { connection: result });
         assert_not_equals(e, null);
         assert_equals(e.connection, result);
diff --git a/third_party/WebKit/LayoutTests/presentation/presentationrequest.html b/third_party/WebKit/LayoutTests/presentation/presentationrequest.html
index 2deab27..d7338c5 100644
--- a/third_party/WebKit/LayoutTests/presentation/presentationrequest.html
+++ b/third_party/WebKit/LayoutTests/presentation/presentationrequest.html
@@ -6,42 +6,50 @@
 <script src="../resources/gc.js"></script>
 <script>
 
-var presentationUrl = "http://example.com";
-var presentationUrls = [presentationUrl, "cast://google.com/app_id=deadbeef"];
+const presentationUrl = 'http://example.com';
+const presentationUrls = [presentationUrl, 'cast://google.com/app_id=deadbeef'];
 
-var expectedException = new DOMException('PresentationRequest::start() requires user gesture.', 'InvalidAccessError');
+const expectedException = new DOMException(
+    'PresentationRequest::start() requires user gesture.',
+    'InvalidAccessError');
 
 promise_test(function(t) {
-  var request = new PresentationRequest(presentationUrl);
+  const request = new PresentationRequest(presentationUrl);
   return promise_rejects(t, expectedException, request.start());
-}, "Test that the PresentationRequest.start() with one URL requires user gesture.")
+}, 'Test that the PresentationRequest.start() with one URL requires user gesture.')
 
-promise_test(function(t) {
-  var request = new PresentationRequest(presentationUrls);
-  return promise_rejects(t, expectedException, request.start());
-}, "Test that the PresentationRequest.start() with multiple URLs requires user gesture.")
+promise_test(
+    function(t) {
+      const request = new PresentationRequest(presentationUrls);
+      return promise_rejects(t, expectedException, request.start());
+    },
+    'Test that the PresentationRequest.start() with multiple URLs requires user gesture.')
 
-var testGarbageCollection = function(requestArgument) {
-  navigator.presentation.defaultRequest = new PresentationRequest(requestArgument);
-  navigator.presentation.defaultRequest.onconnectionavailable = function() {  };
-  gc();
-  assert_not_equals(navigator.presentation.defaultRequest.onconnectionavailable, undefined);
-};
+    const testGarbageCollection = function(requestArgument) {
+      navigator.presentation.defaultRequest =
+          new PresentationRequest(requestArgument);
+      navigator.presentation.defaultRequest.onconnectionavailable = function() {
+      };
+      gc();
+      assert_not_equals(
+          navigator.presentation.defaultRequest.onconnectionavailable,
+          undefined);
+    };
 
 test(function() {
   testGarbageCollection(presentationUrl);
-}, "Test that navigator.presentation.defaultRequest.onconnectionavailable with one URL isn't reset after gc().");
+}, 'Test that navigator.presentation.defaultRequest.onconnectionavailable with one URL isn\'t reset after gc().');
 
 test(function() {
   testGarbageCollection(presentationUrls);
-}, "Test that navigator.presentation.defaultRequest.onconnectionavailable with multiple URLs isn't reset after gc().");
+}, 'Test that navigator.presentation.defaultRequest.onconnectionavailable with multiple URLs isn\'t reset after gc().');
 
 test(function() {
-  var request = new PresentationRequest("http://example.com");
-  var promise_1 = request.getAvailability();
-  var promise_2 = request.getAvailability();
+  const request = new PresentationRequest('http://example.com');
+  const promise_1 = request.getAvailability();
+  const promise_2 = request.getAvailability();
   assert_true(promise_1 === promise_2);
-}, "Test that the PresentationRequest.getAvailability() returns same promise object.");
+}, 'Test that the PresentationRequest.getAvailability() returns same promise object.');
 
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/presentation/resources/embedded-smoke-tests.html b/third_party/WebKit/LayoutTests/presentation/resources/embedded-smoke-tests.html
index 2769287..8dddc30 100644
--- a/third_party/WebKit/LayoutTests/presentation/resources/embedded-smoke-tests.html
+++ b/third_party/WebKit/LayoutTests/presentation/resources/embedded-smoke-tests.html
@@ -3,8 +3,8 @@
 <body>
 <script>
 
-var FAKE_SESSION_ID = 'fake';
-var gCurrentConnection = null;
+const FAKE_SESSION_ID = 'fake';
+let gCurrentConnection = null;
 
 // Returns the test runner used to run this test..
 // Current possible values are 'blink' and 'manual'.
@@ -24,7 +24,7 @@
         setTimeout(resolve);
         break;
       case 'manual':
-        var button = document.createElement('button');
+        const button = document.createElement('button');
         button.textContent = 'click me';
         button.onclick = function() {
           document.body.removeChild(button);
@@ -38,18 +38,18 @@
   });
 }
 
-var results = [];
+const results = [];
 
 // start()
 getUserGesture().then(function() {
   if (getTestRunner() == 'manual') {
-    var description = document.createElement('div');
+    const description = document.createElement('div');
     description.id = 'description';
     description.textContent = 'Pick a device if asked for it';
     document.body.appendChild(description);
   }
 
-  var p = new PresentationRequest('https://example.com');
+  const p = new PresentationRequest('https://example.com');
   return p.start().then(function(connection) {
     gCurrentConnection = connection;
     results.push({ test: 'start', status: 'success' })
@@ -62,8 +62,10 @@
 }).then(function() {
   // reconnect()
   return getUserGesture().then(function() {
-    var p = new PresentationRequest('https://example.com');
-    return p.reconnect(gCurrentConnection ? gCurrentConnection.id : FAKE_SESSION_ID).then(function() {
+    const p = new PresentationRequest('https://example.com');
+    return p.reconnect(gCurrentConnection ?
+                       gCurrentConnection.id :
+                       FAKE_SESSION_ID).then(function() {
       results.push({ test: 'reconnect', status: 'success' })
     }, function(e) {
       results.push({ test: 'reconnect', status: 'failure', name: e.name });
@@ -72,7 +74,7 @@
 }).then(function() {
   // getAvailability()
   return getUserGesture().then(function() {
-    var p = new PresentationRequest('https://example.com');
+    const p = new PresentationRequest('https://example.com');
     return p.getAvailability().then(function() {
       results.push({ test: 'getAvailability', status: 'success' })
     }, function(e) {
diff --git a/third_party/WebKit/LayoutTests/presentation/resources/presentation-service-mock.js b/third_party/WebKit/LayoutTests/presentation/resources/presentation-service-mock.js
index 3db3d1e..eee573b 100644
--- a/third_party/WebKit/LayoutTests/presentation/resources/presentation-service-mock.js
+++ b/third_party/WebKit/LayoutTests/presentation/resources/presentation-service-mock.js
@@ -4,13 +4,12 @@
 
 "use strict";
 
-let presentationServiceMock = loadMojoModules(
-    'presentationServiceMock',
-    [
+const presentationServiceMock =
+    loadMojoModules('presentationServiceMock', [
       'third_party/WebKit/public/platform/modules/presentation/presentation.mojom',
       'mojo/public/js/bindings',
     ]).then(mojo => {
-      let [ presentationService, bindings ] = mojo.modules;
+      const [presentationService, bindings] = mojo.modules;
 
       class PresentationServiceMock {
         constructor(interfaceProvider) {
@@ -23,6 +22,8 @@
               presentationService.PresentationService);
         }
 
+        setClient(client) { this.client_ = client; }
+
         startSession(urls) {
           return Promise.resolve({
               sessionInfo: { url: urls[0], id: 'fakesession' },
@@ -36,6 +37,12 @@
               error: null,
           });
         }
+
+        closeConnection(url, id) {
+          this.client_.onConnectionClosed(
+              {url: url, id: id},
+              presentationService.PresentationConnectionCloseReason.CLOSED, '');
+        }
       }
 
       return new PresentationServiceMock(mojo.frameInterfaces);
@@ -47,9 +54,9 @@
   if (!('eventSender' in window))
     return;
 
-  var boundingRect = button.getBoundingClientRect();
-  var x = boundingRect.left + boundingRect.width / 2;
-  var y = boundingRect.top + boundingRect.height / 2;
+  const boundingRect = button.getBoundingClientRect();
+  const x = boundingRect.left + boundingRect.width / 2;
+  const y = boundingRect.top + boundingRect.height / 2;
 
   eventSender.mouseMoveTo(x, y);
   eventSender.mouseDown();
diff --git a/third_party/WebKit/LayoutTests/virtual/feature-policy/http/tests/feature-policy/fullscreen-disabled-expected.txt b/third_party/WebKit/LayoutTests/virtual/feature-policy/http/tests/feature-policy/fullscreen-disabled-expected.txt
index ca7eb48..48c1d107 100644
--- a/third_party/WebKit/LayoutTests/virtual/feature-policy/http/tests/feature-policy/fullscreen-disabled-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/feature-policy/http/tests/feature-policy/fullscreen-disabled-expected.txt
@@ -1,7 +1,3 @@
-CONSOLE WARNING: line 15: Fullscreen API is disabled by feature policy for this frame
-CONSOLE WARNING: line 6: Fullscreen API is disabled by feature policy for this frame
-CONSOLE WARNING: line 15: Fullscreen API is disabled by feature policy for this frame
-CONSOLE WARNING: line 6: Fullscreen API is disabled by feature policy for this frame
 This is a testharness.js-based test.
 PASS Fullscreen disabled on URL: resources/feature-policy-fullscreen.html with allowfullscreen = false 
 PASS Fullscreen disabled on URL: http://localhost:8000/feature-policy/resources/feature-policy-fullscreen.html with allowfullscreen = false 
diff --git a/third_party/WebKit/LayoutTests/virtual/feature-policy/http/tests/feature-policy/fullscreen-enabledforall-expected.txt b/third_party/WebKit/LayoutTests/virtual/feature-policy/http/tests/feature-policy/fullscreen-enabledforall-expected.txt
new file mode 100644
index 0000000..40207bb1e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/feature-policy/http/tests/feature-policy/fullscreen-enabledforall-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+PASS Fullscreen enabled for all on URL: resources/feature-policy-fullscreen.html with allowfullscreen = false 
+PASS Fullscreen enabled for all on URL: http://localhost:8000/feature-policy/resources/feature-policy-fullscreen.html with allowfullscreen = false 
+PASS Fullscreen enabled for all on URL: resources/feature-policy-fullscreen.html with allowfullscreen = true 
+PASS Fullscreen enabled for all on URL: http://localhost:8000/feature-policy/resources/feature-policy-fullscreen.html with allowfullscreen = true 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/Source/core/css/ActiveStyleSheets.cpp b/third_party/WebKit/Source/core/css/ActiveStyleSheets.cpp
index de06afc..893c790 100644
--- a/third_party/WebKit/Source/core/css/ActiveStyleSheets.cpp
+++ b/third_party/WebKit/Source/core/css/ActiveStyleSheets.cpp
@@ -44,7 +44,7 @@
     bool ruleSetsChangedInCommonPrefix = !changedRuleSets.isEmpty();
     for (; index < newStyleSheetCount; index++) {
       if (newStyleSheets[index].second)
-        changedRuleSets.add(newStyleSheets[index].second);
+        changedRuleSets.insert(newStyleSheets[index].second);
     }
     if (ruleSetsChangedInCommonPrefix)
       return ActiveSheetsChanged;
@@ -57,7 +57,7 @@
     // Sheets removed from the end.
     for (; index < oldStyleSheetCount; index++) {
       if (oldStyleSheets[index].second)
-        changedRuleSets.add(oldStyleSheets[index].second);
+        changedRuleSets.insert(oldStyleSheets[index].second);
     }
     return changedRuleSets.isEmpty() ? NoActiveSheetsChanged
                                      : ActiveSheetsChanged;
@@ -86,7 +86,7 @@
         (*mergedIterator).first != sheet1.first) {
       // Sheet either removed or inserted.
       if (sheet1.second)
-        changedRuleSets.add(sheet1.second);
+        changedRuleSets.insert(sheet1.second);
       continue;
     }
 
@@ -99,9 +99,9 @@
     // Active rules for the given stylesheet changed.
     // DOM, CSSOM, or media query changes.
     if (sheet1.second)
-      changedRuleSets.add(sheet1.second);
+      changedRuleSets.insert(sheet1.second);
     if (sheet2.second)
-      changedRuleSets.add(sheet2.second);
+      changedRuleSets.insert(sheet2.second);
   }
   return changedRuleSets.isEmpty() ? NoActiveSheetsChanged
                                    : ActiveSheetsChanged;
diff --git a/third_party/WebKit/Source/core/dom/Fullscreen.cpp b/third_party/WebKit/Source/core/dom/Fullscreen.cpp
index 5ead996..5fbb037d 100644
--- a/third_party/WebKit/Source/core/dom/Fullscreen.cpp
+++ b/third_party/WebKit/Source/core/dom/Fullscreen.cpp
@@ -63,19 +63,52 @@
   if (!frame)
     return false;
 
-  // 2. If |document|'s browsing context is a top-level browsing context, then
-  // return true.
-  if (frame->isMainFrame())
+  if (!RuntimeEnabledFeatures::featurePolicyEnabled()) {
+    // 2. If |document|'s browsing context is a top-level browsing context, then
+    // return true.
+    if (frame->isMainFrame())
+      return true;
+
+    // 3. If |document|'s browsing context has a browsing context container that
+    // is an iframe element with an |allowattribute| attribute specified, and
+    // whose node document is allowed to use the feature indicated by
+    // |allowattribute|, then return true.
+    if (frame->owner() && frame->owner()->allowFullscreen())
+      return allowedToUseFullscreen(frame->tree().parent());
+
+    // 4. Return false.
+    return false;
+  }
+
+  // If Feature Policy is enabled, then we need this hack to support it, until
+  // we have proper support for <iframe allowfullscreen> in FP:
+
+  // 1. If FP, by itself, enables fullscreen in this document, then fullscreen
+  // is allowed.
+  if (frame->securityContext()->getFeaturePolicy()->isFeatureEnabled(
+          kFullscreenFeature)) {
     return true;
+  }
 
-  // 3. If |document|'s browsing context has a browsing context container that
-  // is an iframe element with an |allowattribute| attribute specified, and
-  // whose node document is allowed to use the feature indicated by
-  // |allowattribute|, then return true.
-  if (frame->owner() && frame->owner()->allowFullscreen())
-    return allowedToUseFullscreen(frame->tree().parent());
+  // 2. Otherwise, if the embedding frame's document is allowed to use
+  // fullscreen (either through FP or otherwise), and either:
+  //   a) this is a same-origin embedded document, or
+  //   b) this document's iframe has the allowfullscreen attribute set,
+  // then fullscreen is allowed.
+  if (!frame->isMainFrame()) {
+    if (allowedToUseFullscreen(frame->tree().parent())) {
+      return (frame->owner() && frame->owner()->allowFullscreen()) ||
+             frame->tree()
+                 .parent()
+                 ->securityContext()
+                 ->getSecurityOrigin()
+                 ->isSameSchemeHostPortAndSuborigin(
+                     frame->securityContext()->getSecurityOrigin());
+    }
+  }
 
-  // 4. Return false.
+  // Otherwise, fullscreen is not allowed. (If we reach here and this is the
+  // main frame, then fullscreen must have been disabled by FP.)
   return false;
 }
 
@@ -104,43 +137,14 @@
 }
 
 // https://fullscreen.spec.whatwg.org/#fullscreen-is-supported
-// TODO(lunalu): update the placement of the feature policy code once it is in
-// https://fullscreen.spec.whatwg.org/.
-bool fullscreenIsSupported(Document& document) {
+bool fullscreenIsSupported(const Document& document) {
   LocalFrame* frame = document.frame();
   if (!frame)
     return false;
 
   // Fullscreen is supported if there is no previously-established user
   // preference, security risk, or platform limitation.
-  bool fullscreenSupported =
-      !document.settings() || document.settings()->getFullscreenSupported();
-
-  if (!RuntimeEnabledFeatures::featurePolicyEnabled()) {
-    return fullscreenSupported;
-  }
-
-  // TODO(lunalu): clean all of this up once iframe attributes are supported
-  // for feature policy.
-  if (Frame* parent = frame->tree().parent()) {
-    // If FeaturePolicy is enabled, check the fullscreen is not disabled by
-    // policy in the parent frame.
-    if (fullscreenSupported &&
-        parent->securityContext()->getFeaturePolicy()->isFeatureEnabled(
-            kFullscreenFeature)) {
-      return true;
-    }
-  }
-  // Even if the iframe allowfullscreen attribute is not present, allow
-  // fullscreen to be enabled by feature policy.
-  else if (isFeatureEnabledInFrame(kFullscreenFeature, frame)) {
-    return true;
-  }
-
-  document.addConsoleMessage(ConsoleMessage::create(
-      JSMessageSource, WarningMessageLevel,
-      "Fullscreen API is disabled by feature policy for this frame"));
-  return false;
+  return !document.settings() || document.settings()->getFullscreenSupported();
 }
 
 // https://fullscreen.spec.whatwg.org/#fullscreen-element-ready-check
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index fed6ff0..492fabd 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -4106,7 +4106,7 @@
   }
   DCHECK(needsCustom && isCustom);
   DCHECK(styleSource);
-  if (toLayoutScrollbar(scrollbar)->owningLayoutObject() !=
+  if (toLayoutScrollbar(scrollbar)->styleSource() !=
       styleSource->layoutObject()) {
     // We have a custom scrollbar with a stale m_owner.
     return true;
@@ -4656,6 +4656,13 @@
         ->intersectionObserverController()
         ->computeTrackedIntersectionObservations();
 
+  // Don't throttle display:none frames (see updateRenderThrottlingStatus).
+  HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
+  if (m_hiddenForThrottling && ownerElement && !ownerElement->layoutObject()) {
+    updateRenderThrottlingStatus(m_hiddenForThrottling, m_subtreeThrottled);
+    DCHECK(!canThrottleRendering());
+  }
+
   for (Frame* child = m_frame->tree().firstChild(); child;
        child = child->tree().nextSibling()) {
     if (!child->isLocalFrame())
@@ -4676,9 +4683,11 @@
   DCHECK(!m_frame->document() || !m_frame->document()->inStyleRecalc());
   bool wasThrottled = canThrottleRendering();
 
-  // Note that we disallow throttling of 0x0 frames because some sites use
-  // them to drive UI logic.
-  m_hiddenForThrottling = hidden && !frameRect().isEmpty();
+  // Note that we disallow throttling of 0x0 and display:none frames because
+  // some sites use them to drive UI logic.
+  HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
+  m_hiddenForThrottling = hidden && !frameRect().isEmpty() &&
+                          (ownerElement && ownerElement->layoutObject());
   m_subtreeThrottled = subtreeThrottled;
 
   bool isThrottled = canThrottleRendering();
diff --git a/third_party/WebKit/Source/core/imagebitmap/OWNERS b/third_party/WebKit/Source/core/imagebitmap/OWNERS
index 46ce301..0d000d3d 100644
--- a/third_party/WebKit/Source/core/imagebitmap/OWNERS
+++ b/third_party/WebKit/Source/core/imagebitmap/OWNERS
@@ -1,2 +1,5 @@
 xidachen@chromium.org
 junov@chromium.org
+
+# TEAM: paint-dev@chromium.org
+# COMPONENT: Blink>Canvas
diff --git a/third_party/WebKit/Source/core/inspector/CodeGeneratorInstrumentation.py b/third_party/WebKit/Source/core/inspector/CodeGeneratorInstrumentation.py
index 559ac64..44febb60 100755
--- a/third_party/WebKit/Source/core/inspector/CodeGeneratorInstrumentation.py
+++ b/third_party/WebKit/Source/core/inspector/CodeGeneratorInstrumentation.py
@@ -122,7 +122,7 @@
 template_instrumenting_agent_impl = string.Template("""
 void InstrumentingAgents::add${class_name}(${class_name}* agent)
 {
-    ${member_name}.add(agent);
+    ${member_name}.insert(agent);
     ${has_member_name} = true;
 }
 
diff --git a/third_party/WebKit/Source/core/layout/FloatingObjects.cpp b/third_party/WebKit/Source/core/layout/FloatingObjects.cpp
index 27b7106..f443714 100644
--- a/third_party/WebKit/Source/core/layout/FloatingObjects.cpp
+++ b/third_party/WebKit/Source/core/layout/FloatingObjects.cpp
@@ -29,8 +29,6 @@
 #include "core/layout/LayoutView.h"
 #include "core/layout/api/LineLayoutBlockFlow.h"
 #include "core/layout/shapes/ShapeOutsideInfo.h"
-#include "core/paint/PaintLayer.h"
-#include "platform/RuntimeEnabledFeatures.h"
 #include "wtf/PtrUtil.h"
 #include <algorithm>
 #include <memory>
@@ -78,6 +76,7 @@
       m_originatingLine(nullptr),
       m_frameRect(frameRect),
       m_type(type),
+      m_shouldPaint(shouldPaint),
       m_isDescendant(isDescendant),
       m_isPlaced(true),
       m_isLowestNonOverhangingFloatInChild(isLowestNonOverhangingFloatInChild)
@@ -86,22 +85,6 @@
       m_isInPlacedTree(false)
 #endif
 {
-  m_shouldPaint = shouldPaint || shouldPaintForCompositedLayoutPart();
-}
-
-bool FloatingObject::shouldPaintForCompositedLayoutPart() {
-  // HACK: only non-self-painting floats should paint. However, due to the
-  // fundamental compositing bug, some LayoutPart objects may become
-  // self-painting due to being composited. This leads to a chicken-egg issue
-  // because layout may not depend on compositing.
-  // If this is the case, set shouldPaint() to true even if the layer is
-  // technically self-painting. This lets the float which contains a LayoutPart
-  // start painting as soon as it stops being composited, without having to
-  // re-layout the float.
-  // This hack can be removed after SPv2.
-  return m_layoutObject->layer() &&
-         m_layoutObject->layer()->isSelfPaintingOnlyBecauseIsCompositedPart() &&
-         !RuntimeEnabledFeatures::slimmingPaintV2Enabled();
 }
 
 std::unique_ptr<FloatingObject> FloatingObject::create(
@@ -111,18 +94,13 @@
 
   // If a layer exists, the float will paint itself. Otherwise someone else
   // will.
-  newObj->setShouldPaint(!layoutObject->hasSelfPaintingLayer() ||
-                         newObj->shouldPaintForCompositedLayoutPart());
+  newObj->setShouldPaint(!layoutObject->hasSelfPaintingLayer());
 
   newObj->setIsDescendant(true);
 
   return newObj;
 }
 
-bool FloatingObject::shouldPaint() const {
-  return m_shouldPaint && !m_layoutObject->hasSelfPaintingLayer();
-}
-
 std::unique_ptr<FloatingObject> FloatingObject::copyToNewContainer(
     LayoutSize offset,
     bool shouldPaint,
diff --git a/third_party/WebKit/Source/core/layout/FloatingObjects.h b/third_party/WebKit/Source/core/layout/FloatingObjects.h
index c838dd1..fb83563 100644
--- a/third_party/WebKit/Source/core/layout/FloatingObjects.h
+++ b/third_party/WebKit/Source/core/layout/FloatingObjects.h
@@ -113,7 +113,7 @@
   void setIsInPlacedTree(bool value) { m_isInPlacedTree = value; }
 #endif
 
-  bool shouldPaint() const;
+  bool shouldPaint() const { return m_shouldPaint; }
   void setShouldPaint(bool shouldPaint) { m_shouldPaint = shouldPaint; }
   bool isDescendant() const { return m_isDescendant; }
   void setIsDescendant(bool isDescendant) { m_isDescendant = isDescendant; }
@@ -139,8 +139,6 @@
                  bool isDescendant,
                  bool isLowestNonOverhangingFloatInChild);
 
-  bool shouldPaintForCompositedLayoutPart();
-
   LayoutBox* m_layoutObject;
   RootInlineBox* m_originatingLine;
   LayoutRect m_frameRect;
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
index f2f945d..359acb05 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -3998,7 +3998,9 @@
   for (FloatingObjectSetIterator it = floatingObjectSet.end(); it != begin;) {
     --it;
     const FloatingObject& floatingObject = *it->get();
-    if (floatingObject.shouldPaint()) {
+    if (floatingObject.shouldPaint() &&
+        // TODO(wangxianzhu): Should this be a DCHECK?
+        !floatingObject.layoutObject()->hasSelfPaintingLayer()) {
       LayoutUnit xOffset = xPositionForFloatIncludingMargin(floatingObject) -
                            floatingObject.layoutObject()->location().x();
       LayoutUnit yOffset = yPositionForFloatIncludingMargin(floatingObject) -
@@ -4051,7 +4053,7 @@
   return fixedOffset;
 }
 
-void LayoutBlockFlow::setAncestorShouldPaintFloatingObject(
+void LayoutBlockFlow::updateAncestorShouldPaintFloatingObject(
     const LayoutBox& floatBox) {
   ASSERT(floatBox.isFloating());
   bool floatBoxIsSelfPaintingLayer =
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
index d45ad3a0..0267305 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
@@ -718,7 +718,8 @@
     return m_floatingObjects.get();
   }
 
-  static void setAncestorShouldPaintFloatingObject(const LayoutBox& floatBox);
+  static void updateAncestorShouldPaintFloatingObject(
+      const LayoutBox& floatBox);
 
  protected:
   LayoutUnit maxPositiveMarginBefore() const {
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
index 1bb5c34b..436e96d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -920,7 +920,7 @@
 LayoutBlock* LayoutObject::containingBlock(AncestorSkipInfo* skipInfo) const {
   LayoutObject* object = parent();
   if (!object && isLayoutScrollbarPart())
-    object = toLayoutScrollbarPart(this)->layoutObjectOwningScrollbar();
+    object = toLayoutScrollbarPart(this)->scrollbarStyleSource();
   if (!isTextOrSVGChild()) {
     if (m_style->position() == FixedPosition)
       return containerForFixedPosition(skipInfo);
diff --git a/third_party/WebKit/Source/core/layout/LayoutRubyBase.cpp b/third_party/WebKit/Source/core/layout/LayoutRubyBase.cpp
index 18d3e2f..1a082a5 100644
--- a/third_party/WebKit/Source/core/layout/LayoutRubyBase.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutRubyBase.cpp
@@ -126,10 +126,12 @@
   }
   // Move all remaining children normally. If moving all children, include our
   // float list.
-  if (!beforeChild)
+  if (!beforeChild) {
     moveAllChildrenIncludingFloatsTo(toBase, toBase->hasLayer() || hasLayer());
-  else
+  } else {
     moveChildrenTo(toBase, firstChild(), beforeChild);
+    removeFloatingObjectsFromDescendants();
+  }
 }
 
 ETextAlign LayoutRubyBase::textAlignmentForLine(
diff --git a/third_party/WebKit/Source/core/layout/LayoutScrollbar.cpp b/third_party/WebKit/Source/core/layout/LayoutScrollbar.cpp
index 6160de0..35ccf55 100644
--- a/third_party/WebKit/Source/core/layout/LayoutScrollbar.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutScrollbar.cpp
@@ -41,20 +41,20 @@
 Scrollbar* LayoutScrollbar::createCustomScrollbar(
     ScrollableArea* scrollableArea,
     ScrollbarOrientation orientation,
-    Node* ownerNode) {
-  return new LayoutScrollbar(scrollableArea, orientation, ownerNode);
+    Element* styleSource) {
+  return new LayoutScrollbar(scrollableArea, orientation, styleSource);
 }
 
 LayoutScrollbar::LayoutScrollbar(ScrollableArea* scrollableArea,
                                  ScrollbarOrientation orientation,
-                                 Node* ownerNode)
+                                 Element* styleSource)
     : Scrollbar(scrollableArea,
                 orientation,
                 RegularScrollbar,
                 nullptr,
                 LayoutScrollbarTheme::layoutScrollbarTheme()),
-      m_owner(ownerNode) {
-  DCHECK(ownerNode);
+      m_styleSource(styleSource) {
+  DCHECK(styleSource);
 
   // FIXME: We need to do this because LayoutScrollbar::styleChanged is called
   // as soon as the scrollbar is created.
@@ -89,13 +89,13 @@
 }
 
 DEFINE_TRACE(LayoutScrollbar) {
-  visitor->trace(m_owner);
+  visitor->trace(m_styleSource);
   Scrollbar::trace(visitor);
 }
 
-LayoutBox* LayoutScrollbar::owningLayoutObject() const {
-  return m_owner && m_owner->layoutObject()
-             ? m_owner->layoutObject()->enclosingBox()
+LayoutBox* LayoutScrollbar::styleSource() const {
+  return m_styleSource && m_styleSource->layoutObject()
+             ? m_styleSource->layoutObject()->enclosingBox()
              : 0;
 }
 
@@ -146,12 +146,11 @@
 PassRefPtr<ComputedStyle> LayoutScrollbar::getScrollbarPseudoStyle(
     ScrollbarPart partType,
     PseudoId pseudoId) {
-  if (!owningLayoutObject())
+  if (!styleSource())
     return nullptr;
 
-  return owningLayoutObject()->getUncachedPseudoStyle(
-      PseudoStyleRequest(pseudoId, this, partType),
-      owningLayoutObject()->style());
+  return styleSource()->getUncachedPseudoStyle(
+      PseudoStyleRequest(pseudoId, this, partType), styleSource()->style());
 }
 
 void LayoutScrollbar::updateScrollbarParts(bool destroy) {
@@ -184,7 +183,7 @@
     setFrameRect(
         IntRect(location(), IntSize(isHorizontal ? width() : newThickness,
                                     isHorizontal ? newThickness : height())));
-    if (LayoutBox* box = owningLayoutObject()) {
+    if (LayoutBox* box = styleSource()) {
       if (box->isLayoutBlock())
         toLayoutBlock(box)->notifyScrollbarThicknessChanged();
       box->setChildNeedsLayout();
@@ -266,7 +265,7 @@
   LayoutScrollbarPart* partLayoutObject = m_parts.get(partType);
   if (!partLayoutObject && needLayoutObject && m_scrollableArea) {
     partLayoutObject = LayoutScrollbarPart::createAnonymous(
-        &owningLayoutObject()->document(), m_scrollableArea, this, partType);
+        &styleSource()->document(), m_scrollableArea, this, partType);
     m_parts.set(partType, partLayoutObject);
     setNeedsPaintInvalidation(partType);
   } else if (partLayoutObject && !needLayoutObject) {
diff --git a/third_party/WebKit/Source/core/layout/LayoutScrollbar.h b/third_party/WebKit/Source/core/layout/LayoutScrollbar.h
index 961623d8..bd8363b 100644
--- a/third_party/WebKit/Source/core/layout/LayoutScrollbar.h
+++ b/third_party/WebKit/Source/core/layout/LayoutScrollbar.h
@@ -34,18 +34,21 @@
 namespace blink {
 
 class ComputedStyle;
+class Element;
 class LayoutBox;
 class LayoutScrollbarPart;
-class Node;
 
 class LayoutScrollbar final : public Scrollbar {
  public:
   static Scrollbar* createCustomScrollbar(ScrollableArea*,
                                           ScrollbarOrientation,
-                                          Node*);
+                                          Element*);
   ~LayoutScrollbar() override;
 
-  LayoutBox* owningLayoutObject() const;
+  // The LayoutBox that supplies our style information. If the scrollbar is for
+  // a document, this is either the <body> or <html> element. Otherwise, it is
+  // the element that owns our PaintLayerScrollableArea.
+  LayoutBox* styleSource() const;
 
   IntRect buttonRect(ScrollbarPart) const;
   IntRect trackRect(int startLength, int endLength) const;
@@ -67,7 +70,7 @@
   DECLARE_VIRTUAL_TRACE();
 
  protected:
-  LayoutScrollbar(ScrollableArea*, ScrollbarOrientation, Node*);
+  LayoutScrollbar(ScrollableArea*, ScrollbarOrientation, Element*);
 
  private:
   friend class Scrollbar;
@@ -87,13 +90,8 @@
   PassRefPtr<ComputedStyle> getScrollbarPseudoStyle(ScrollbarPart, PseudoId);
   void updateScrollbarPart(ScrollbarPart, bool destroy = false);
 
-  // This Scrollbar(Widget) may outlive the DOM which created it (during tear
-  // down), so we keep a reference to the Node which caused this custom
-  // scrollbar creation.
-  // This will not create a reference cycle as the Widget tree is owned by our
-  // containing FrameView which this Node pointer can in no way keep alive.
-  // See webkit bug 80610.
-  Member<Node> m_owner;
+  // The element that supplies our style information.
+  Member<Element> m_styleSource;
 
   HashMap<unsigned, LayoutScrollbarPart*> m_parts;
 };
diff --git a/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp b/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp
index 3de0ff8..5239ca7 100644
--- a/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp
@@ -133,17 +133,16 @@
 }
 
 void LayoutScrollbarPart::computeScrollbarWidth() {
-  if (!m_scrollbar->owningLayoutObject())
+  if (!m_scrollbar->styleSource())
     return;
   // FIXME: We are querying layout information but nothing guarantees that it's
   // up to date, especially since we are called at style change.
   // FIXME: Querying the style's border information doesn't work on table cells
   // with collapsing borders.
-  int visibleSize =
-      (m_scrollbar->owningLayoutObject()->size().width() -
-       m_scrollbar->owningLayoutObject()->style()->borderLeftWidth() -
-       m_scrollbar->owningLayoutObject()->style()->borderRightWidth())
-          .toInt();
+  int visibleSize = (m_scrollbar->styleSource()->size().width() -
+                     m_scrollbar->styleSource()->style()->borderLeftWidth() -
+                     m_scrollbar->styleSource()->style()->borderRightWidth())
+                        .toInt();
   int w = calcScrollbarThicknessUsing(MainOrPreferredSize, style()->width(),
                                       visibleSize);
   int minWidth =
@@ -163,17 +162,16 @@
 }
 
 void LayoutScrollbarPart::computeScrollbarHeight() {
-  if (!m_scrollbar->owningLayoutObject())
+  if (!m_scrollbar->styleSource())
     return;
   // FIXME: We are querying layout information but nothing guarantees that it's
   // up to date, especially since we are called at style change.
   // FIXME: Querying the style's border information doesn't work on table cells
   // with collapsing borders.
-  int visibleSize =
-      (m_scrollbar->owningLayoutObject()->size().height() -
-       m_scrollbar->owningLayoutObject()->style()->borderTopWidth() -
-       m_scrollbar->owningLayoutObject()->style()->borderBottomWidth())
-          .toInt();
+  int visibleSize = (m_scrollbar->styleSource()->size().height() -
+                     m_scrollbar->styleSource()->style()->borderTopWidth() -
+                     m_scrollbar->styleSource()->style()->borderBottomWidth())
+                        .toInt();
   int h = calcScrollbarThicknessUsing(MainOrPreferredSize, style()->height(),
                                       visibleSize);
   int minHeight =
@@ -225,8 +223,8 @@
   LayoutBlock::imageChanged(image, rect);
 }
 
-LayoutObject* LayoutScrollbarPart::layoutObjectOwningScrollbar() const {
-  return (!m_scrollbar) ? nullptr : m_scrollbar->owningLayoutObject();
+LayoutObject* LayoutScrollbarPart::scrollbarStyleSource() const {
+  return (!m_scrollbar) ? nullptr : m_scrollbar->styleSource();
 }
 
 void LayoutScrollbarPart::setNeedsPaintInvalidation() {
diff --git a/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.h b/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.h
index ff76ed9..1266fcf 100644
--- a/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.h
+++ b/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.h
@@ -74,7 +74,7 @@
     return type == LayoutObjectLayoutScrollbarPart ||
            LayoutBlock::isOfType(type);
   }
-  LayoutObject* layoutObjectOwningScrollbar() const;
+  LayoutObject* scrollbarStyleSource() const;
 
   // Must call setStyleWithWritingModeOfParent() instead.
   void setStyle(PassRefPtr<ComputedStyle>) = delete;
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingInputsUpdater.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositingInputsUpdater.cpp
index 2c1b53b..dbfd4cf 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositingInputsUpdater.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositingInputsUpdater.cpp
@@ -247,6 +247,17 @@
   layer->didUpdateCompositingInputs();
 
   m_geometryMap.popMappingsToAncestor(layer->parent());
+
+  if (layer->selfPaintingStatusChanged()) {
+    layer->clearSelfPaintingStatusChanged();
+    // If the floating object becomes non-self-painting, so some ancestor should
+    // paint it; if it becomes self-painting, it should paint itself and no
+    // ancestor should paint it.
+    if (layer->layoutObject()->isFloating()) {
+      LayoutBlockFlow::updateAncestorShouldPaintFloatingObject(
+          *layer->layoutBox());
+    }
+  }
 }
 
 #if DCHECK_IS_ON()
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
index aadb712..cfbeae94 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -208,7 +208,7 @@
   for (NGBlockNode* node = first_child_; node; node = node->NextSibling()) {
     Optional<MinAndMaxContentSizes> child_minmax;
     if (NeedMinAndMaxContentSizesForContentContribution(*node->Style())) {
-      child_minmax = node->ComputeMinAndMaxContentSizesSync();
+      child_minmax = node->ComputeMinAndMaxContentSizes();
     }
 
     MinAndMaxContentSizes child_sizes =
@@ -614,7 +614,7 @@
   if (NeedMinAndMaxContentSizes(space, style)) {
     // TODO(ikilpatrick): Change ComputeMinAndMaxContentSizes to return
     // MinAndMaxContentSizes.
-    sizes = current_child_->ComputeMinAndMaxContentSizesSync();
+    sizes = current_child_->ComputeMinAndMaxContentSizes();
   }
   LayoutUnit child_inline_size =
       ComputeInlineSizeForFragment(space, style, sizes);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
index 882d9c3..d193674 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
@@ -95,29 +95,23 @@
   return fragment_;
 }
 
-MinAndMaxContentSizes NGBlockNode::ComputeMinAndMaxContentSizesSync() {
+MinAndMaxContentSizes NGBlockNode::ComputeMinAndMaxContentSizes() {
   MinAndMaxContentSizes sizes;
-  while (!ComputeMinAndMaxContentSizes(&sizes))
-    continue;
-  return sizes;
-}
-
-bool NGBlockNode::ComputeMinAndMaxContentSizes(MinAndMaxContentSizes* sizes) {
   if (!CanUseNewLayout()) {
     DCHECK(layout_box_);
     // TODO(layout-ng): This could be somewhat optimized by directly calling
     // computeIntrinsicLogicalWidths, but that function is currently private.
     // Consider doing that if this becomes a performance issue.
     LayoutUnit borderAndPadding = layout_box_->borderAndPaddingLogicalWidth();
-    sizes->min_content = layout_box_->computeLogicalWidthUsing(
-                             MainOrPreferredSize, Length(MinContent),
-                             LayoutUnit(), layout_box_->containingBlock()) -
-                         borderAndPadding;
-    sizes->max_content = layout_box_->computeLogicalWidthUsing(
-                             MainOrPreferredSize, Length(MaxContent),
-                             LayoutUnit(), layout_box_->containingBlock()) -
-                         borderAndPadding;
-    return true;
+    sizes.min_content = layout_box_->computeLogicalWidthUsing(
+                            MainOrPreferredSize, Length(MinContent),
+                            LayoutUnit(), layout_box_->containingBlock()) -
+                        borderAndPadding;
+    sizes.max_content = layout_box_->computeLogicalWidthUsing(
+                            MainOrPreferredSize, Length(MaxContent),
+                            LayoutUnit(), layout_box_->containingBlock()) -
+                        borderAndPadding;
+    return sizes;
   }
 
   NGConstraintSpace* constraint_space =
@@ -129,8 +123,8 @@
   // TODO(cbiesinger): For orthogonal children, we need to always synthesize.
   NGBlockLayoutAlgorithm minmax_algorithm(
       layout_box_, Style(), toNGBlockNode(FirstChild()), constraint_space);
-  if (minmax_algorithm.ComputeMinAndMaxContentSizes(sizes))
-    return true;
+  if (minmax_algorithm.ComputeMinAndMaxContentSizes(&sizes))
+    return sizes;
 
   // Have to synthesize this value.
   NGPhysicalFragment* physical_fragment = Layout(constraint_space);
@@ -138,7 +132,7 @@
       FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(),
       toNGPhysicalBoxFragment(physical_fragment));
 
-  sizes->min_content = fragment->InlineOverflow();
+  sizes.min_content = fragment->InlineOverflow();
 
   // Now, redo with infinite space for max_content
   constraint_space =
@@ -153,8 +147,8 @@
   fragment = new NGBoxFragment(
       FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(),
       toNGPhysicalBoxFragment(physical_fragment));
-  sizes->max_content = fragment->InlineOverflow();
-  return true;
+  sizes.max_content = fragment->InlineOverflow();
+  return sizes;
 }
 
 ComputedStyle* NGBlockNode::MutableStyle() {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
index 088fdaf..28d3574 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
@@ -38,16 +38,10 @@
   LayoutObject* GetLayoutObject() override;
 
   // Computes the value of min-content and max-content for this box.
-  // The return value has the same meaning as for Layout.
   // If the underlying layout algorithm returns NotImplemented from
   // ComputeMinAndMaxContentSizes, this function will synthesize these sizes
   // using Layout with special constraint spaces.
-  // It is not legal to interleave a pending Layout() with a pending
-  // ComputeOrSynthesizeMinAndMaxContentSizes (i.e. you have to call Layout
-  // often enough that it returns true before calling
-  // ComputeOrSynthesizeMinAndMaxContentSizes)
-  bool ComputeMinAndMaxContentSizes(MinAndMaxContentSizes*);
-  MinAndMaxContentSizes ComputeMinAndMaxContentSizesSync();
+  MinAndMaxContentSizes ComputeMinAndMaxContentSizes();
 
   const ComputedStyle* Style() const;
   ComputedStyle* MutableStyle();
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node_test.cc
index 6c1822d4..656723f2 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_node_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node_test.cc
@@ -27,9 +27,7 @@
   NGBlockNode* box = new NGBlockNode(style_.get());
   box->SetFirstChild(first_child);
 
-  MinAndMaxContentSizes sizes;
-  while (!box->ComputeMinAndMaxContentSizes(&sizes))
-    continue;
+  MinAndMaxContentSizes sizes = box->ComputeMinAndMaxContentSizes();
   EXPECT_EQ(LayoutUnit(kWidth), sizes.min_content);
   EXPECT_EQ(LayoutUnit(kWidth), sizes.max_content);
 }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
index 87f50db..cdbda4f8 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -101,7 +101,7 @@
   Optional<LayoutUnit> block_estimate;
 
   if (AbsoluteNeedsChildInlineSize(*descendant.Style())) {
-    inline_estimate = descendant.ComputeMinAndMaxContentSizesSync();
+    inline_estimate = descendant.ComputeMinAndMaxContentSizes();
   }
 
   NGAbsolutePhysicalPosition node_position =
diff --git a/third_party/WebKit/Source/core/offscreencanvas/OWNERS b/third_party/WebKit/Source/core/offscreencanvas/OWNERS
index f8e160a..f0de60d 100644
--- a/third_party/WebKit/Source/core/offscreencanvas/OWNERS
+++ b/third_party/WebKit/Source/core/offscreencanvas/OWNERS
@@ -1,3 +1,6 @@
 junov@chromium.org
 xlai@chromium.org
 xidachen@chromium.org
+
+# TEAM: paint-dev@chromium.org
+# COMPONENT: Blink>Canvas
diff --git a/third_party/WebKit/Source/core/paint/BlockFlowPainter.cpp b/third_party/WebKit/Source/core/paint/BlockFlowPainter.cpp
index 816eaf5..0ac6dd65 100644
--- a/third_party/WebKit/Source/core/paint/BlockFlowPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/BlockFlowPainter.cpp
@@ -53,6 +53,10 @@
       continue;
 
     const LayoutBox* floatingLayoutObject = floatingObject->layoutObject();
+    // TODO(wangxianzhu): Should this be a DCHECK?
+    if (floatingLayoutObject->hasSelfPaintingLayer())
+      continue;
+
     // FIXME: LayoutPoint version of xPositionForFloatIncludingMargin would make
     // this much cleaner.
     LayoutPoint childPoint = m_layoutBlockFlow.flipFloatForWritingModeForChild(
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
index 168383e4..8ee0faf 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -157,6 +157,7 @@
       m_hasNonIsolatedDescendantWithBlendMode(false),
       m_hasAncestorWithClipPath(false),
       m_hasRootScrollerAsDescendant(false),
+      m_selfPaintingStatusChanged(false),
       m_layoutObject(layoutObject),
       m_parent(0),
       m_previous(0),
@@ -1516,15 +1517,7 @@
 }
 
 void PaintLayer::didUpdateNeedsCompositedScrolling() {
-  bool wasSelfPaintingLayer = isSelfPaintingLayer();
   updateSelfPaintingLayer();
-
-  // If the floating object becomes non-self-painting, so some ancestor should
-  // paint it; if it becomes self-painting, it should paint itself and no
-  // ancestor should paint it.
-  if (wasSelfPaintingLayer != isSelfPaintingLayer() &&
-      m_layoutObject->isFloating())
-    LayoutBlockFlow::setAncestorShouldPaintFloatingObject(*layoutBox());
 }
 
 void PaintLayer::updateStackingNode() {
@@ -2793,22 +2786,14 @@
   return false;
 }
 
-bool PaintLayer::isSelfPaintingLayerForIntrinsicOrScrollingReasons() const {
-  return layoutObject()->layerTypeRequired() == NormalPaintLayer ||
-         (m_scrollableArea && m_scrollableArea->hasOverlayScrollbars()) ||
-         needsCompositedScrolling();
-}
-
 bool PaintLayer::shouldBeSelfPaintingLayer() const {
   if (layoutObject()->isLayoutPart() &&
       toLayoutPart(layoutObject())->requiresAcceleratedCompositing())
     return true;
-  return isSelfPaintingLayerForIntrinsicOrScrollingReasons();
-}
 
-bool PaintLayer::isSelfPaintingOnlyBecauseIsCompositedPart() const {
-  return shouldBeSelfPaintingLayer() &&
-         !isSelfPaintingLayerForIntrinsicOrScrollingReasons();
+  return layoutObject()->layerTypeRequired() == NormalPaintLayer ||
+         (m_scrollableArea && m_scrollableArea->hasOverlayScrollbars()) ||
+         needsCompositedScrolling();
 }
 
 void PaintLayer::updateSelfPaintingLayer() {
@@ -2817,6 +2802,7 @@
     return;
 
   m_isSelfPaintingLayer = isSelfPaintingLayer;
+  m_selfPaintingStatusChanged = true;
 
   if (PaintLayer* parent = this->parent()) {
     parent->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.h b/third_party/WebKit/Source/core/paint/PaintLayer.h
index f57327c..75eb3c31 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.h
@@ -250,10 +250,6 @@
   // FIXME: Many people call this function while it has out-of-date information.
   bool isSelfPaintingLayer() const { return m_isSelfPaintingLayer; }
 
-  // PaintLayers which represent LayoutParts may become self-painting due to
-  // being composited.  If this is the case, this method returns true.
-  bool isSelfPaintingOnlyBecauseIsCompositedPart() const;
-
   bool isTransparent() const {
     return layoutObject()->isTransparent() ||
            layoutObject()->style()->hasBlendMode() || layoutObject()->hasMask();
@@ -988,6 +984,17 @@
     return m_has3DTransformedDescendant;
   }
 
+  // Whether the value of isSelfPaintingLayer() changed since the last clearing
+  // (which happens after the flag is chedked during compositing update).
+  bool selfPaintingStatusChanged() const {
+    DCHECK(!RuntimeEnabledFeatures::slimmingPaintV2Enabled());
+    return m_selfPaintingStatusChanged;
+  }
+  void clearSelfPaintingStatusChanged() {
+    DCHECK(!RuntimeEnabledFeatures::slimmingPaintV2Enabled());
+    m_selfPaintingStatusChanged = false;
+  }
+
 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
   void endShouldKeepAliveAllClientsRecursive();
 #endif
@@ -1115,8 +1122,6 @@
         layer.m_needsPaintPhaseDescendantBlockBackgrounds;
   }
 
-  bool isSelfPaintingLayerForIntrinsicOrScrollingReasons() const;
-
   bool shouldFragmentCompositedBounds(const PaintLayer* compositingLayer) const;
 
   void expandRectForStackingChildren(const PaintLayer& compositedLayer,
@@ -1199,6 +1204,8 @@
   unsigned m_hasAncestorWithClipPath : 1;
   unsigned m_hasRootScrollerAsDescendant : 1;
 
+  unsigned m_selfPaintingStatusChanged : 1;
+
   LayoutBoxModelObject* m_layoutObject;
 
   PaintLayer* m_parent;
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index 07efaa1..894d81f 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -1104,7 +1104,7 @@
   return IntSize();
 }
 
-static inline const LayoutObject& layoutObjectForScrollbar(
+static inline const LayoutObject& scrollbarStyleSource(
     const LayoutObject& layoutObject) {
   if (Node* node = layoutObject.node()) {
     if (layoutObject.isLayoutView()) {
@@ -1142,10 +1142,10 @@
 }
 
 bool PaintLayerScrollableArea::needsScrollbarReconstruction() const {
-  const LayoutObject& actualLayoutObject = layoutObjectForScrollbar(box());
+  const LayoutObject& styleSource = scrollbarStyleSource(box());
   bool shouldUseCustom =
-      actualLayoutObject.isBox() &&
-      actualLayoutObject.styleRef().hasPseudoStyle(PseudoIdScrollbar);
+      styleSource.isBox() &&
+      styleSource.styleRef().hasPseudoStyle(PseudoIdScrollbar);
   bool hasAnyScrollbar = hasScrollbar();
   bool hasCustom =
       (hasHorizontalScrollbar() &&
@@ -1154,14 +1154,12 @@
   bool didCustomScrollbarOwnerChanged = false;
 
   if (hasHorizontalScrollbar() && horizontalScrollbar()->isCustomScrollbar()) {
-    if (actualLayoutObject !=
-        toLayoutScrollbar(horizontalScrollbar())->owningLayoutObject())
+    if (styleSource != toLayoutScrollbar(horizontalScrollbar())->styleSource())
       didCustomScrollbarOwnerChanged = true;
   }
 
   if (hasVerticalScrollbar() && verticalScrollbar()->isCustomScrollbar()) {
-    if (actualLayoutObject !=
-        toLayoutScrollbar(verticalScrollbar())->owningLayoutObject())
+    if (styleSource != toLayoutScrollbar(verticalScrollbar())->styleSource())
       didCustomScrollbarOwnerChanged = true;
   }
 
@@ -1332,12 +1330,12 @@
   if (!m_scrollCorner && hasOverlayScrollbars())
     return;
 
-  const LayoutObject& actualLayoutObject = layoutObjectForScrollbar(box());
+  const LayoutObject& styleSource = scrollbarStyleSource(box());
   RefPtr<ComputedStyle> corner =
       box().hasOverflowClip()
-          ? actualLayoutObject.getUncachedPseudoStyle(
+          ? styleSource.getUncachedPseudoStyle(
                 PseudoStyleRequest(PseudoIdScrollbarCorner),
-                actualLayoutObject.style())
+                styleSource.style())
           : PassRefPtr<ComputedStyle>(nullptr);
   if (corner) {
     if (!m_scrollCorner) {
@@ -1490,11 +1488,11 @@
   if (!m_resizer && !box().canResize())
     return;
 
-  const LayoutObject& actualLayoutObject = layoutObjectForScrollbar(box());
+  const LayoutObject& styleSource = scrollbarStyleSource(box());
   RefPtr<ComputedStyle> resizer =
       box().hasOverflowClip()
-          ? actualLayoutObject.getUncachedPseudoStyle(
-                PseudoStyleRequest(PseudoIdResizer), actualLayoutObject.style())
+          ? styleSource.getUncachedPseudoStyle(
+                PseudoStyleRequest(PseudoIdResizer), styleSource.style())
           : PassRefPtr<ComputedStyle>(nullptr);
   if (resizer) {
     if (!m_resizer) {
@@ -1967,19 +1965,21 @@
   DCHECK(orientation == HorizontalScrollbar ? !m_hBarIsAttached
                                             : !m_vBarIsAttached);
   Scrollbar* scrollbar = nullptr;
-  const LayoutObject& actualLayoutObject =
-      layoutObjectForScrollbar(scrollableArea()->box());
+  const LayoutObject& styleSource =
+      scrollbarStyleSource(scrollableArea()->box());
   bool hasCustomScrollbarStyle =
-      actualLayoutObject.isBox() &&
-      actualLayoutObject.styleRef().hasPseudoStyle(PseudoIdScrollbar);
+      styleSource.isBox() &&
+      styleSource.styleRef().hasPseudoStyle(PseudoIdScrollbar);
   if (hasCustomScrollbarStyle) {
+    DCHECK(styleSource.node() && styleSource.node()->isElementNode());
     scrollbar = LayoutScrollbar::createCustomScrollbar(
-        scrollableArea(), orientation, actualLayoutObject.node());
+        scrollableArea(), orientation, toElement(styleSource.node()));
   } else {
     ScrollbarControlSize scrollbarSize = RegularScrollbar;
-    if (actualLayoutObject.styleRef().hasAppearance())
+    if (styleSource.styleRef().hasAppearance()) {
       scrollbarSize = LayoutTheme::theme().scrollbarControlSizeForPart(
-          actualLayoutObject.styleRef().appearance());
+          styleSource.styleRef().appearance());
+    }
     scrollbar = Scrollbar::create(
         scrollableArea(), orientation, scrollbarSize,
         &scrollableArea()->box().frame()->page()->chromeClient());
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn
index 9255c841..af7a035 100644
--- a/third_party/WebKit/Source/devtools/BUILD.gn
+++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -720,6 +720,10 @@
   "front_end/Images/accelerometer-left.png",
   "front_end/Images/accelerometer-right.png",
   "front_end/Images/accelerometer-top.png",
+  "front_end/Images/audits_logo.png",
+  "front_end/Images/audits_logo_2x.png",
+  "front_end/Images/audits_logo_bw.png",
+  "front_end/Images/audits_logo_bw_2x.png",
   "front_end/Images/applicationCache.png",
   "front_end/Images/breakpoint.png",
   "front_end/Images/breakpoint_2x.png",
@@ -797,6 +801,7 @@
   "$resources_out_dir/inspector.js",
   "$resources_out_dir/toolbox.html",
   "$resources_out_dir/toolbox.js",
+  "$resources_out_dir/audits2_worker.js",
   "$resources_out_dir/formatter_worker.js",
   "$resources_out_dir/heap_snapshot_worker.js",
   "$resources_out_dir/utility_shared_worker.js",
@@ -804,6 +809,7 @@
   # this contains non-autostart non-remote modules only.
   "$resources_out_dir/animation/animation_module.js",
   "$resources_out_dir/audits/audits_module.js",
+  "$resources_out_dir/audits2_worker/audits2_worker_module.js",
   "$resources_out_dir/audits2/audits2_module.js",
   "$resources_out_dir/cm/cm_module.js",
   "$resources_out_dir/color_picker/color_picker_module.js",
@@ -848,6 +854,7 @@
   "toolbox",
   "unit_test_runner",
   "formatter_worker",
+  "audits2_worker",
   "heap_snapshot_worker",
   "utility_shared_worker",
 ]
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/audits_logo.png b/third_party/WebKit/Source/devtools/front_end/Images/audits_logo.png
new file mode 100644
index 0000000..4c3a7e7
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/Images/audits_logo.png
Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/audits_logo_2x.png b/third_party/WebKit/Source/devtools/front_end/Images/audits_logo_2x.png
new file mode 100644
index 0000000..46f3fea0
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/Images/audits_logo_2x.png
Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/audits_logo_bw.png b/third_party/WebKit/Source/devtools/front_end/Images/audits_logo_bw.png
new file mode 100644
index 0000000..4835e22b
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/Images/audits_logo_bw.png
Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/audits_logo_bw_2x.png b/third_party/WebKit/Source/devtools/front_end/Images/audits_logo_bw_2x.png
new file mode 100644
index 0000000..d4ccb3a
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/Images/audits_logo_bw_2x.png
Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/audits_logo.svg b/third_party/WebKit/Source/devtools/front_end/Images/src/audits_logo.svg
new file mode 100644
index 0000000..89a25cc7
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/Images/src/audits_logo.svg
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="96" height="96" viewBox="0 0 96 96">
+  <title>audits_logo_96_final</title>
+  <defs>
+    <rect id="a" x="16" y="12" width="64" height="80" rx="6" />
+    <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="b">
+      <feOffset dy="1" in="SourceAlpha" result="shadowOffsetInner1" />
+      <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1" />
+      <feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.2 0" in="shadowInnerInner1" result="shadowMatrixInner1" />
+      <feOffset dy="-1" in="SourceAlpha" result="shadowOffsetInner2" />
+      <feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2" />
+      <feColorMatrix values="0 0 0 0 0.756862745 0 0 0 0 0.207843137 0 0 0 0 0 0 0 0 0.2 0" in="shadowInnerInner2" result="shadowMatrixInner2" />
+      <feMerge>
+        <feMergeNode in="shadowMatrixInner1" />
+        <feMergeNode in="shadowMatrixInner2" />
+      </feMerge>
+    </filter>
+    <rect id="c" width="64" height="80" rx="6" />
+    <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="d">
+      <feOffset dy="1" in="SourceAlpha" result="shadowOffsetInner1" />
+      <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1" />
+      <feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.2 0" in="shadowInnerInner1" result="shadowMatrixInner1" />
+      <feOffset dy="-1" in="SourceAlpha" result="shadowOffsetInner2" />
+      <feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2" />
+      <feColorMatrix values="0 0 0 0 0.756862745 0 0 0 0 0.207843137 0 0 0 0 0 0 0 0 0.2 0" in="shadowInnerInner2" result="shadowMatrixInner2" />
+      <feMerge>
+        <feMergeNode in="shadowMatrixInner1" />
+        <feMergeNode in="shadowMatrixInner2" />
+      </feMerge>
+    </filter>
+    <path d="M40.923 2.182c3.095.885 5.614 2.216 7.206 3.818h5.877A3.993 3.993 0 0 1 58 10v60c0 2.21-1.79 4-3.994 4H9.994A3.993 3.993 0 0 1 6 70V10c0-2.21 1.79-4 3.994-4h5.877c1.592-1.602 4.111-2.933 7.206-3.818a9 9 0 1 1 17.846 0zM32 4a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" id="g" />
+    <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="f">
+      <feOffset dx="4" dy="4" in="SourceAlpha" result="shadowOffsetOuter1" />
+      <feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
+      <feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
+      <feColorMatrix values="0 0 0 0 0.756862745 0 0 0 0 0.207843137 0 0 0 0 0 0 0 0 0.2 0" in="shadowBlurOuter1" />
+    </filter>
+    <rect id="h" width="52" height="68" rx="4" />
+    <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="i">
+      <feOffset dy="1" in="SourceAlpha" result="shadowOffsetInner1" />
+      <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1" />
+      <feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.2 0" in="shadowInnerInner1" result="shadowMatrixInner1" />
+      <feOffset dy="-1" in="SourceAlpha" result="shadowOffsetInner2" />
+      <feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2" />
+      <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0" in="shadowInnerInner2" result="shadowMatrixInner2" />
+      <feMerge>
+        <feMergeNode in="shadowMatrixInner1" />
+        <feMergeNode in="shadowMatrixInner2" />
+      </feMerge>
+    </filter>
+    <path d="M36 18c0-3.347-3.654-6.267-9.077-7.818a9 9 0 1 0-17.846 0C3.654 11.732 0 14.652 0 18h36zm-18-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" id="j" />
+    <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="k">
+      <feOffset dy="1" in="SourceAlpha" result="shadowOffsetInner1" />
+      <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1" />
+      <feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.2 0" in="shadowInnerInner1" result="shadowMatrixInner1" />
+      <feOffset dy="-1" in="SourceAlpha" result="shadowOffsetInner2" />
+      <feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2" />
+      <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0" in="shadowInnerInner2" result="shadowMatrixInner2" />
+      <feMerge>
+        <feMergeNode in="shadowMatrixInner1" />
+        <feMergeNode in="shadowMatrixInner2" />
+      </feMerge>
+    </filter>
+    <path d="M40.945 8a9.001 9.001 0 0 0-17.89 0H5.992A5.998 5.998 0 0 0 0 13.997v68.006A5.994 5.994 0 0 0 5.992 88h52.016A5.998 5.998 0 0 0 64 82.003V13.997A5.994 5.994 0 0 0 58.008 8H40.945zM34.83 8a3.001 3.001 0 0 0-5.658 0h5.658z" id="l" />
+    <radialGradient cx="0%" cy="0%" fx="0%" fy="0%" r="141.421%" id="m">
+      <stop stop-color="#FFF" stop-opacity=".1" offset="0%" />
+      <stop stop-color="#FFF" stop-opacity="0" offset="100%" />
+    </radialGradient>
+  </defs>
+  <g fill="none" fill-rule="evenodd">
+    <use fill="#F6B500" xlink:href="#a" />
+    <use fill="#000" filter="url(#b)" xlink:href="#a" />
+    <g transform="translate(16 12)">
+      <mask id="e" fill="#fff">
+        <use xlink:href="#c" />
+      </mask>
+      <use fill="#F6B500" xlink:href="#c" />
+      <use fill="#000" filter="url(#d)" xlink:href="#c" />
+      <g mask="url(#e)">
+        <use fill="#000" filter="url(#f)" xlink:href="#g" />
+        <use fill-opacity="0" fill="#F5F5F5" xlink:href="#g" />
+      </g>
+    </g>
+    <g transform="translate(22 18)">
+      <use fill="#F5F5F5" xlink:href="#h" />
+      <use fill="#000" filter="url(#i)" xlink:href="#h" />
+    </g>
+    <path fill="#F5F5F5" d="M30 34h36v36H30z" />
+    <path fill="#0E9C57" d="M44.666 65.404L65.04 45.126l-4.233-4.252-16.073 16.018-6.589-6.74-4.29 4.195z" />
+    <g>
+      <g transform="translate(30 4)">
+        <use fill="#616161" xlink:href="#j" />
+        <use fill="#000" filter="url(#k)" xlink:href="#j" />
+      </g>
+    </g>
+    <g transform="translate(16 4)">
+      <mask id="n" fill="#fff">
+        <use xlink:href="#l" />
+      </mask>
+      <use fill-opacity="0" fill="#F6B500" xlink:href="#l" />
+      <path fill="url(#m)" mask="url(#n)" d="M-16-4h96v96h-96z" />
+    </g>
+  </g>
+</svg>
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/audits_logo_bw.svg b/third_party/WebKit/Source/devtools/front_end/Images/src/audits_logo_bw.svg
new file mode 100644
index 0000000..a4958e2
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/Images/src/audits_logo_bw.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 48 48">
+  <title>audits_logo_48_final</title>
+  <path d="M33 11c0-1.674-1.827-3.134-4.538-3.909a4.5 4.5 0 1 0-8.923 0C16.826 7.866 15 9.326 15 11h18zM16.97 6h-5.974A2.997 2.997 0 0 0 8 9.007v33.986A2.999 2.999 0 0 0 10.996 46h26.008A2.997 2.997 0 0 0 40 42.993V9.007A2.999 2.999 0 0 0 37.004 6h-5.975c1.584.778 2.793 1.815 3.44 3h.534C36.106 9 37 9.892 37 11v30c0 1.105-.895 2-1.997 2H12.997A1.996 1.996 0 0 1 11 41V11c0-1.105.895-2 1.997-2h.534c.647-1.185 1.856-2.222 3.44-3zm4.305 25.62l1.058 1.082 1.073-1.067 9.114-9.072-2.116-2.126-8.036 8.01-3.295-3.371-2.146 2.097 4.348 4.447zM24 8a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z" fill="#CCC" fill-rule="evenodd" />
+</svg>
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
index ea846dc..80c095d47 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
+++ b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
@@ -1,11 +1,13 @@
 {
     "securityIcons.svg": "27676f7c1f1542659c7c49a8052259dc",
     "resourceGlyphs.svg": "8e1947b1fa4aac49cbc081f85f44d412",
+    "search.svg": "fc990dd3836aec510d7ca1f36c2a3142",
     "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28",
     "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45",
     "smallIcons.svg": "e42007c7e8da94ecab276fd254f0623e",
     "settingsListRemove.svg": "ce9e7c5c5cdaef28e6ee51d9478d5485",
     "toolbarButtonGlyphs.svg": "a2f97ba793fb31f61930f934c0837e34",
     "breakpoint.svg": "69cd92d807259c022791112809b97799",
-    "search.svg": "fc990dd3836aec510d7ca1f36c2a3142"
+    "audits_logo_bw.svg": "203dcb2ba32ef0f4595ad45bb8feffab",
+    "audits_logo.svg": "0790aa567cc61be5484a30490c41147b"
 }
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
index e997de2..0da03669 100644
--- a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
+++ b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
@@ -1,59 +1,286 @@
 // 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.
+
+/**
+ * @typedef {{
+ *     lighthouseVersion: !string,
+ *     generatedTime: !string,
+ *     initialUrl: !string,
+ *     url: !string,
+ *     audits: ?Object,
+ *     aggregations: !Array<*>
+ * }}
+ */
+Audits2.LighthouseResult;
+
+/**
+ * @typedef {{
+ *     blobUrl: !string,
+ *     result: !Audits2.LighthouseResult
+ * }}
+ */
+Audits2.WorkerResult;
+
 /**
  * @unrestricted
  */
 Audits2.Audits2Panel = class extends UI.Panel {
   constructor() {
     super('audits2');
-    this.contentElement.classList.add('vbox');
-    this.contentElement.appendChild(UI.createTextButton(Common.UIString('Start'), this._start.bind(this)));
-    this.contentElement.appendChild(UI.createTextButton(Common.UIString('Stop'), this._stop.bind(this)));
-    this._resultElement = this.contentElement.createChild('div', 'overflow-auto');
+    this.setHideOnDetach();
+    this.registerRequiredCSS('audits2/audits2Panel.css');
+
+    this._protocolService = new Audits2.ProtocolService();
+    this._protocolService.registerStatusCallback(msg => this._updateStatus(Common.UIString(msg)));
+
+    this._pwaSetting = Common.settings.createSetting('audits2_pwa', true);
+    this._perfSetting = Common.settings.createSetting('audits2_perf', true);
+    this._practicesSetting = Common.settings.createSetting('audits2_best_practices', true);
+
+    var auditsViewElement = this.contentElement.createChild('div', 'hbox audits-view');
+    this._resultsView = this.contentElement.createChild('div', 'vbox results-view');
+    auditsViewElement.appendChild(createElementWithClass('div', 'audits2-logo'));
+    auditsViewElement.appendChild(this._createLauncherUI());
+  }
+
+  _reset() {
+    this.contentElement.classList.remove('show-results');
+    this._resultsView.removeChildren();
+  }
+
+  /**
+   * @param {string} name
+   * @param {!Common.Setting} setting
+   * @return {!UI.ToolbarItem}
+   */
+  _createSettingCheckbox(name, setting) {
+    const checkboxItem = new UI.ToolbarCheckbox(name, undefined, setting);
+    return checkboxItem;
+  }
+
+  _createLauncherUI() {
+    var uiElement = createElement('div');
+    var headerElement = uiElement.createChild('header');
+    headerElement.createChild('p').textContent = Common.UIString(
+        'Audits will analyze the page against modern development best practices and collect useful performance metrics and diagnostics. Select audits to collect:');
+    uiElement.appendChild(headerElement);
+
+    var auditSelectorForm = uiElement.createChild('form', 'audits2-form');
+
+    var perfCheckbox =
+        this._createSettingCheckbox(Common.UIString('Performance metrics and diagnostics'), this._perfSetting);
+    var pwaCheckbox = this._createSettingCheckbox(Common.UIString('Progressive web app audits'), this._pwaSetting);
+    var practicesCheckbox =
+        this._createSettingCheckbox(Common.UIString('Modern web development best practices'), this._practicesSetting);
+    [perfCheckbox, practicesCheckbox, pwaCheckbox].forEach(checkbox => auditSelectorForm.appendChild(checkbox.element));
+
+    this._startButton = UI.createTextButton(
+        Common.UIString('Audit this page'), this._startButtonClicked.bind(this), 'run-audit audit-btn');
+    auditSelectorForm.appendChild(this._startButton);
+
+    this._statusView = this._createStatusView();
+    uiElement.appendChild(this._statusView);
+    return uiElement;
+  }
+
+  /**
+   * @return {!Element}
+   */
+  _createStatusView() {
+    var statusView = createElementWithClass('div', 'audits2-status hbox hidden');
+    statusView.createChild('span', 'icon');
+    this._statusElement = createElement('p');
+    statusView.appendChild(this._statusElement);
+    this._updateStatus(Common.UIString('Loading...'));
+    return statusView;
   }
 
   _start() {
-    SDK.targetManager.interceptMainConnection(this._dispatchProtocolMessage.bind(this)).then(rawConnection => {
-      this._rawConnection = rawConnection;
-      this._send('start').then(result => {
-        var section = new Components.ObjectPropertiesSection(
-            SDK.RemoteObject.fromLocalObject(result), Common.UIString('Audit Results'));
-        this._resultElement.appendChild(section.element);
-        this._stop();
-      });
+    this._auditRunning = true;
+    this._updateButton();
+    this._updateStatus(Common.UIString('Loading...'));
+
+    this._inspectedURL = SDK.targetManager.mainTarget().inspectedURL();
+    const aggregationTags = [this._pwaSetting, this._perfSetting, this._practicesSetting].map(
+        setting => ({id: setting.name.replace('audits2_', ''), value: setting.get()}));
+
+    return Promise.resolve()
+        .then(_ => this._protocolService.attach())
+        .then(_ => this._protocolService.startLighthouse(this._inspectedURL, aggregationTags))
+        .then(workerResult => {
+          this._finish(workerResult);
+          return this._stop();
+        });
+  }
+
+  /**
+   * @param {!Event} event
+   */
+  _startButtonClicked(event) {
+    if (this._auditRunning) {
+      this._updateStatus(Common.UIString('Cancelling...'));
+      this._stop();
+      return;
+    }
+    this._start();
+  }
+
+  _updateButton() {
+    this._startButton.textContent =
+        this._auditRunning ? Common.UIString('Cancel audit') : Common.UIString('Audit this page');
+    this._startButton.classList.toggle('started', this._auditRunning);
+    this._statusView.classList.toggle('hidden', !this._auditRunning);
+  }
+
+  /**
+   * @param {string} statusMessage
+   */
+  _updateStatus(statusMessage) {
+    this._statusElement.textContent = statusMessage;
+  }
+
+  /**
+   * @return {!Promise<undefined>}
+   */
+  _stop() {
+    return this._protocolService.detach().then(_ => {
+      this._auditRunning = false;
+      this._updateButton();
+      if (this._inspectedURL !== SDK.targetManager.mainTarget().inspectedURL())
+        SDK.targetManager.mainTarget().pageAgent().navigate(this._inspectedURL);
+
     });
   }
 
   /**
+   * @param {!Audits2.WorkerResult} workerResult
+   */
+  _finish(workerResult) {
+    if (workerResult === null) {
+      this._updateStatus(Common.UIString('Auditing failed.'));
+      return;
+    }
+    this._resultsView.removeChildren();
+
+    this._resultsView.appendChild(this._createResultsBar(workerResult.result.url, workerResult.result.generatedTime));
+    this._resultsView.appendChild(this._createIframe(workerResult.blobUrl));
+    this.contentElement.classList.add('show-results');
+  }
+
+  /**
+   * @param {string} blobUrl
+   * @return {!Element}
+   */
+  _createIframe(blobUrl) {
+    var iframeContainer = createElementWithClass('div', 'iframe-container');
+    var iframe = iframeContainer.createChild('iframe', 'fill');
+    iframe.setAttribute('sandbox', 'allow-scripts allow-popups-to-escape-sandbox allow-popups');
+    iframe.src = blobUrl;
+    return iframeContainer;
+  }
+
+  /**
+   * @param {string} url
+   * @param {string} timestamp
+   * @return {!Element}
+   */
+  _createResultsBar(url, timestamp) {
+    var elem = createElementWithClass('div', 'results-bar hbox');
+    elem.createChild('div', 'audits2-logo audits2-logo-small');
+
+    var summaryElem = elem.createChild('div', 'audits2-summary');
+    var reportFor = summaryElem.createChild('span');
+    reportFor.createTextChild('Report for ');
+    var urlElem = reportFor.createChild('b');
+    urlElem.textContent = url;
+    var timeElem = summaryElem.createChild('span');
+    timeElem.textContent =
+        `Generated at ${new Date(timestamp).toLocaleDateString()} ${new Date(timestamp).toLocaleTimeString()}`;
+
+    var newAuditButton =
+        UI.createTextButton(Common.UIString('New Audit'), this._reset.bind(this), 'new-audit audit-btn');
+    elem.appendChild(newAuditButton);
+    return elem;
+  }
+};
+
+Audits2.ProtocolService = class extends Common.Object {
+  constructor() {
+    super();
+    /** @type {?Protocol.InspectorBackend.Connection} */
+    this._rawConnection = null;
+    /** @type {?Services.ServiceManager.Service} */
+    this._backend = null;
+    /** @type {?Promise} */
+    this._backendPromise = null;
+    /** @type {?function(string)} */
+    this._status = null;
+  }
+
+  /**
+   * @return {!Promise<undefined>}
+   */
+  attach() {
+    return SDK.targetManager.interceptMainConnection(this._dispatchProtocolMessage.bind(this)).then(rawConnection => {
+      this._rawConnection = rawConnection;
+    });
+  }
+
+  /**
+   * @param {string} inspectedURL
+   * @param {!Array<!{id: string, value: boolean}>} aggregationTags
+   * @return {!Promise<!Audits2.WorkerResult|undefined>}
+   */
+  startLighthouse(inspectedURL, aggregationTags) {
+    return this._send('start', {url: inspectedURL, aggregationTags});
+  }
+
+  /**
+   * @return {!Promise<!Object|undefined>}
+   */
+  detach() {
+    return Promise.resolve().then(() => this._send('stop')).then(() => this._backend.dispose()).then(() => {
+      delete this._backend;
+      delete this._backendPromise;
+      return this._rawConnection.disconnect();
+    });
+  }
+
+  /**
+   *  @param {function (string): undefined} callback
+   */
+  registerStatusCallback(callback) {
+    this._status = callback;
+  }
+
+  /**
    * @param {string} message
    */
   _dispatchProtocolMessage(message) {
     this._send('dispatchProtocolMessage', {message: message});
   }
 
-  _stop() {
-    this._send('stop').then(() => {
-      this._rawConnection.disconnect();
-      this._backend.dispose();
-      delete this._backend;
-      delete this._backendPromise;
-    });
+  _initWorker() {
+    this._backendPromise =
+        Services.serviceManager.createAppService('audits2_worker', 'Audits2Service', false).then(backend => {
+          if (this._backend)
+            return;
+          this._backend = backend;
+          this._backend.on('statusUpdate', result => this._status(result.message));
+          this._backend.on('sendProtocolMessage', result => this._rawConnection.sendMessage(result.message));
+        });
   }
 
   /**
    * @param {string} method
    * @param {!Object=} params
-   * @return {!Promise<!Object|undefined>}
+   * @return {!Promise<!Audits2.WorkerResult|undefined>}
    */
   _send(method, params) {
-    if (!this._backendPromise) {
-      this._backendPromise =
-          Services.serviceManager.createAppService('audits2_worker', 'Audits2Service', false).then(backend => {
-            this._backend = backend;
-            this._backend.on('sendProtocolMessage', result => this._rawConnection.sendMessage(result.message));
-          });
-    }
-    return this._backendPromise.then(() => this._backend ? this._backend.send(method, params) : undefined);
+    if (!this._backendPromise)
+      this._initWorker();
+
+    return this._backendPromise.then(_ => this._backend.send(method, params));
   }
 };
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2/audits2Panel.css b/third_party/WebKit/Source/devtools/front_end/audits2/audits2Panel.css
new file mode 100644
index 0000000..02955aa
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/audits2/audits2Panel.css
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2008 Apple Inc.  All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+iframe {
+    width: 100%;
+    height: 100%;
+    flex-direction: column !important;
+    position: relative;
+    flex: auto;
+}
+
+.audits-view {
+    max-width: 550px;
+    min-width: 334px;
+    align-self: center;
+    margin-top: 30px;
+    margin: 30px 20px;
+}
+
+.results-view {
+    display: none;
+    flex-wrap: nowrap;
+    justify-content: flex-start;
+    align-content: stretch;
+    align-items: stretch;
+}
+
+.show-results .audits-view {
+    display: none;
+}
+
+.show-results .results-view {
+    display: flex;
+    flex: 1;
+}
+
+.results-bar {
+    flex: 0 0;
+    align-self: auto;
+    border-bottom: 1px solid #cccccc;
+}
+
+.audits2-summary {display: flex;flex-direction: column;flex-grow: 1;padding: 6px;line-height: 1.7;align-self: center;}
+
+.audits2-summary span {
+    color: #b7b7b7;
+    display: block;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
+.audits2-summary span b {
+    font-weight: normal;
+    color: #636382;
+}
+
+.audits2-summary span:first-child {
+    color: inherit;
+    font-size: 110%;
+}
+
+.audits2-logo {
+    width: 100px;
+    height: 110px;
+    flex-shrink: 0;
+    background-repeat: no-repeat;
+    background-size: contain;
+    margin-top: 10px;
+    background-image: -webkit-image-set(
+        url(Images/audits_logo.png) 1x,
+        url(Images/audits_logo_2x.png) 2x);
+}
+
+.audits2-logo-small {
+    background-image: -webkit-image-set(
+        url(Images/audits_logo_bw.png) 1x,
+        url(Images/audits_logo_bw_2x.png) 2x);
+    height: 41px;
+    width: 42px;
+    align-self: center;
+    margin: 0 0 0 20px;
+    flex-shrink: 0;
+}
+
+.iframe-container {
+    flex: 1 1 auto;
+    align-self: auto;
+    position: relative;
+}
+
+.audits2-form label {
+    display: block;
+}
+
+.audits2-form label div {
+    display: inline;
+}
+
+button.audit-btn {
+    display: inline-block;
+    font-family: BlinkMacSystemFont, '.SFNSDisplay-Regular', 'Helvetica Neue', 'Lucida Grande', sans-serif;
+    color: white;
+    text-shadow: none;
+    padding: 6px 10px;
+    background-color: #4285f4 !important;
+    background-image: unset !important;
+    font-size: 11px;
+    box-shadow: none !important;
+}
+
+button.audit-btn:hover {
+    background-color: hsla(217, 89%, 58%, 1) !important;
+    color: white !important;
+}
+
+button.run-audit {
+    margin-top: 12px;
+}
+button.run-audit.started {
+    background-color: #ffffff !important;
+    color: gray;
+}
+
+button.run-audit.started:hover {
+    background-color: #eee !important;
+    color: gray !important;
+}
+
+button.new-audit {
+    align-self: center;
+    margin-right: 20px;
+}
+
+.audits2-status .icon {
+    width: 16px;
+    height: 16px;
+    margin-top: 10px;
+    margin-right: 4px;
+    animation: spinner-animation 1200ms linear infinite;
+    transform-origin: 50% 50%;
+    padding: 1px;
+}
+
+.audits2-status .icon::before {
+    display: inline-block;
+    border: 1px solid #1565C0;
+    border-radius: 7px;
+    width: 14px;
+    height: 14px;
+    content: "";
+    position: absolute;
+    box-sizing: border-box;
+}
+
+.audits2-status .icon::after {
+    display: inline-block;
+    width: 6px;
+    height: 7px;
+    background: white;
+    position: absolute;
+    content: "";
+}
+
+@keyframes spinner-animation {
+    from { transform: rotate(0); }
+    to { transform: rotate(360deg); }
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2/module.json b/third_party/WebKit/Source/devtools/front_end/audits2/module.json
index a8a6f78c0..395965f 100644
--- a/third_party/WebKit/Source/devtools/front_end/audits2/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/audits2/module.json
@@ -19,5 +19,8 @@
     "experiment": "audits2",
     "scripts": [
         "Audits2Panel.js"
+    ],
+    "resources": [
+        "audits2Panel.css"
     ]
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2_worker.json b/third_party/WebKit/Source/devtools/front_end/audits2_worker.json
index f9ab83a..417f4a12 100644
--- a/third_party/WebKit/Source/devtools/front_end/audits2_worker.json
+++ b/third_party/WebKit/Source/devtools/front_end/audits2_worker.json
@@ -1,7 +1,7 @@
 {
     "modules": [
         { "name": "worker_service", "type": "autostart" },
-        { "name": "audits2_worker", "type": "remote" }
+        { "name": "audits2_worker"}
     ],
 
     "has_html": false
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2_worker/Audits2Service.js b/third_party/WebKit/Source/devtools/front_end/audits2_worker/Audits2Service.js
index 4ed23ba..c11bd44d 100644
--- a/third_party/WebKit/Source/devtools/front_end/audits2_worker/Audits2Service.js
+++ b/third_party/WebKit/Source/devtools/front_end/audits2_worker/Audits2Service.js
@@ -37,50 +37,27 @@
   }
 
   /**
-   * @return {!Promise}
+   * @return {!Promise<!Audits2.WorkerResult>}
    */
-  start() {
-    return window.runLighthouseInWorker(this, 'https://www.webkit.org', {flags: {mobile: true}}, [
-      'is-on-https',
-      'redirects-http',
-      'service-worker',
-      'works-offline',
-      'viewport',
-      'manifest-display',
-      'without-javascript',
-      'first-meaningful-paint',
-      'speed-index-metric',
-      'estimated-input-latency',
-      'time-to-interactive',
-      'user-timings',
-      'screenshots',
-      'critical-request-chains',
-      'manifest-exists',
-      'manifest-background-color',
-      'manifest-theme-color',
-      'manifest-icons-min-192',
-      'manifest-icons-min-144',
-      'manifest-name',
-      'manifest-short-name',
-      'manifest-short-name-length',
-      'manifest-start-url',
-      'meta-theme-color',
-      'aria-valid-attr',
-      'aria-allowed-attr',
-      'color-contrast',
-      'image-alt',
-      'label',
-      'tabindex',
-      'content-width',
-      'geolocation-on-start'
-    ]);
+  start(params) {
+    const connection = this;
+    const options = undefined;
+
+    self.listenForStatus(message => {
+      this.statusUpdate(message[1]);
+    });
+    return self.runLighthouseInWorker(connection, params.url, options, params.aggregationTags)
+        .then(
+            /** @type {!Audits2.LighthouseResult} */ result =>
+                ({blobUrl: /** @type {?string} */ self.createReportPageAsBlob(result, 'devtools'), result}))
+        .catchException(null);
   }
 
   /**
    * @return {!Promise}
    */
   stop() {
-    this._onClose();
+    this.close();
     return Promise.resolve();
   }
 
@@ -104,6 +81,13 @@
   /**
    * @param {string} message
    */
+  statusUpdate(message) {
+    this._notify('statusUpdate', {message: message});
+  }
+
+  /**
+   * @param {string} message
+   */
   send(message) {
     this._notify('sendProtocolMessage', {message: message});
   }
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js
index ab67b15..5ba641d 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/Main.js
+++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -128,6 +128,8 @@
         Runtime.experiments.enableForTest('accessibilityInspection');
       if (testPath.indexOf('css_tracker') !== -1)
         Runtime.experiments.enableForTest('cssTrackerPanel');
+      if (testPath.indexOf('audits2/') !== -1)
+        Runtime.experiments.enableForTest('audits2');
     }
 
     Runtime.experiments.setDefaultExperiments(['persistenceValidation', 'timelineMultipleMainViews']);
diff --git a/third_party/WebKit/Source/devtools/front_end/perf_ui/TimelineOverviewPane.js b/third_party/WebKit/Source/devtools/front_end/perf_ui/TimelineOverviewPane.js
index 5290412..7ab6735 100644
--- a/third_party/WebKit/Source/devtools/front_end/perf_ui/TimelineOverviewPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/perf_ui/TimelineOverviewPane.js
@@ -472,10 +472,6 @@
    * @return {!{left: number, right: number}}
    */
   windowBoundaries(startTime, endTime) {},
-
-  timelineStarted() {},
-
-  timelineStopped() {},
 };
 
 /**
@@ -544,18 +540,6 @@
   }
 
   /**
-   * @override
-   */
-  timelineStarted() {
-  }
-
-  /**
-   * @override
-   */
-  timelineStopped() {
-  }
-
-  /**
    * @param {!PerfUI.TimelineOverviewCalculator} calculator
    */
   setCalculator(calculator) {
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js b/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js
index dc811a6..5e8d5b2d 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js
@@ -136,8 +136,7 @@
       this.dispatchEventToListeners(Profiler.ProfileType.Events.ProfileComplete, recordedProfile);
     }
 
-    this.profileBeingRecorded()
-        .target()
+    this.profileBeingRecorded().target()
         .heapProfilerModel.stopSampling()
         .then(didStopProfiling.bind(this))
         .then(SDK.targetManager.resumeAllTargets.bind(SDK.targetManager))
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
index 436362b..1f52fc5 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
@@ -467,18 +467,18 @@
     const showMemory = this._showMemorySetting.get();
     const showScreenshots = this._showScreenshotsSetting.get();
     // Set up overview controls.
-    this._overviewControls = [];
-    this._overviewControls.push(new Timeline.TimelineEventOverviewResponsiveness(this._model, this._frameModel));
+    var overviewControls = [];
+    overviewControls.push(new Timeline.TimelineEventOverviewResponsiveness(this._model, this._frameModel));
     if (Runtime.experiments.isEnabled('inputEventsOnTimelineOverview'))
-      this._overviewControls.push(new Timeline.TimelineEventOverviewInput(this._model));
-    this._overviewControls.push(new Timeline.TimelineEventOverviewFrames(this._model, this._frameModel));
-    this._overviewControls.push(new Timeline.TimelineEventOverviewCPUActivity(this._model));
-    this._overviewControls.push(new Timeline.TimelineEventOverviewNetwork(this._model));
+      overviewControls.push(new Timeline.TimelineEventOverviewInput(this._model));
+    overviewControls.push(new Timeline.TimelineEventOverviewFrames(this._model, this._frameModel));
+    overviewControls.push(new Timeline.TimelineEventOverviewCPUActivity(this._model));
+    overviewControls.push(new Timeline.TimelineEventOverviewNetwork(this._model));
     if (showScreenshots)
-      this._overviewControls.push(new Timeline.TimelineFilmStripOverview(this._model, this._filmStripModel));
+      overviewControls.push(new Timeline.TimelineFilmStripOverview(this._model, this._filmStripModel));
     if (showMemory)
-      this._overviewControls.push(new Timeline.TimelineEventOverviewMemory(this._model));
-    this._overviewPane.setOverviewControls(this._overviewControls);
+      overviewControls.push(new Timeline.TimelineEventOverviewMemory(this._model));
+    this._overviewPane.setOverviewControls(overviewControls);
 
     // Set up the main view.
     this._removeAllModeViews();
@@ -585,9 +585,6 @@
     this._controller.startRecording(recordingOptions, enabledTraceProviders);
     this._recordingStartTime = Date.now();
 
-    for (var i = 0; i < this._overviewControls.length; ++i)
-      this._overviewControls[i].timelineStarted();
-
     Host.userMetrics.actionTaken(
         userInitiated ? Host.UserMetrics.Action.TimelineStarted : Host.UserMetrics.Action.TimelinePageReloadStarted);
     this._setUIControlsEnabled(false);
@@ -648,7 +645,7 @@
     this._filmStripModel.reset(this._tracingModel);
     this._overviewPane.reset();
     this._currentViews.forEach(view => view.reset());
-    this._overviewControls.forEach(overview => overview.reset());
+    this._overviewPane.reset();
     this.select(null);
   }
 
@@ -811,8 +808,6 @@
     this._overviewPane.setBounds(this._model.minimumRecordTime(), this._model.maximumRecordTime());
     this._setAutoWindowTimes();
     this._refreshViews();
-    for (var i = 0; i < this._overviewControls.length; ++i)
-      this._overviewControls[i].timelineStopped();
     this._setMarkers();
     this._overviewPane.scheduleUpdate();
     this._updateSearchHighlight(false, true);
diff --git a/third_party/WebKit/Source/devtools/front_end/worker_service/ServiceDispatcher.js b/third_party/WebKit/Source/devtools/front_end/worker_service/ServiceDispatcher.js
index 4fd7a20..b5b69da2 100644
--- a/third_party/WebKit/Source/devtools/front_end/worker_service/ServiceDispatcher.js
+++ b/third_party/WebKit/Source/devtools/front_end/worker_service/ServiceDispatcher.js
@@ -187,7 +187,7 @@
 
 var dispatchers = [];
 
-if (self instanceof SharedWorkerGlobalScope) {
+if (self.SharedWorkerGlobalScope) {
   function onNewPort(port) {
     var dispatcher = new ServiceDispatcher(new WorkerServicePort(port));
     dispatchers.push(dispatcher);
diff --git a/third_party/WebKit/Source/modules/canvas/OWNERS b/third_party/WebKit/Source/modules/canvas/OWNERS
index a0967ed..ba1e518 100644
--- a/third_party/WebKit/Source/modules/canvas/OWNERS
+++ b/third_party/WebKit/Source/modules/canvas/OWNERS
@@ -1,2 +1,5 @@
 junov@chromium.org
 senorblanco@chromium.org
+
+# TEAM: paint-dev@chromium.org
+# COMPONENT: Blink>Canvas
diff --git a/third_party/WebKit/Source/modules/canvas2d/OWNERS b/third_party/WebKit/Source/modules/canvas2d/OWNERS
index a0967ed..ba1e518 100644
--- a/third_party/WebKit/Source/modules/canvas2d/OWNERS
+++ b/third_party/WebKit/Source/modules/canvas2d/OWNERS
@@ -1,2 +1,5 @@
 junov@chromium.org
 senorblanco@chromium.org
+
+# TEAM: paint-dev@chromium.org
+# COMPONENT: Blink>Canvas
diff --git a/third_party/WebKit/Source/modules/csspaint/OWNERS b/third_party/WebKit/Source/modules/csspaint/OWNERS
index 95ba513..2c4ca2f 100644
--- a/third_party/WebKit/Source/modules/csspaint/OWNERS
+++ b/third_party/WebKit/Source/modules/csspaint/OWNERS
@@ -1,2 +1,5 @@
 ikilpatrick@chromium.org
 junov@chromium.org
+
+# TEAM: style-dev@chromium.org
+# COMPONENT: Blink>CSS
diff --git a/third_party/WebKit/Source/modules/imagebitmap/OWNERS b/third_party/WebKit/Source/modules/imagebitmap/OWNERS
index 5d61a12..ba1e518 100644
--- a/third_party/WebKit/Source/modules/imagebitmap/OWNERS
+++ b/third_party/WebKit/Source/modules/imagebitmap/OWNERS
@@ -1,2 +1,5 @@
 junov@chromium.org
-senorblanco@chromium.org
\ No newline at end of file
+senorblanco@chromium.org
+
+# TEAM: paint-dev@chromium.org
+# COMPONENT: Blink>Canvas
diff --git a/third_party/WebKit/Source/modules/offscreencanvas/OWNERS b/third_party/WebKit/Source/modules/offscreencanvas/OWNERS
index b930c975..3288a8a6 100644
--- a/third_party/WebKit/Source/modules/offscreencanvas/OWNERS
+++ b/third_party/WebKit/Source/modules/offscreencanvas/OWNERS
@@ -1,2 +1,5 @@
 junov@chromium.org
 xlai@chromium.org
+
+# TEAM: paint-dev@chromium.org
+# COMPONENT: Blink>Canvas
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OWNERS b/third_party/WebKit/Source/modules/offscreencanvas2d/OWNERS
index b930c975..3288a8a6 100644
--- a/third_party/WebKit/Source/modules/offscreencanvas2d/OWNERS
+++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OWNERS
@@ -1,2 +1,5 @@
 junov@chromium.org
 xlai@chromium.org
+
+# TEAM: paint-dev@chromium.org
+# COMPONENT: Blink>Canvas
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp b/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp
index be94c78b..ff80c76b 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp
+++ b/third_party/WebKit/Source/modules/presentation/PresentationConnection.cpp
@@ -200,6 +200,9 @@
       createSameThreadTask(&PresentationConnection::dispatchEventAsync,
                            wrapPersistent(request), wrapPersistent(event)));
 
+  // Fire onconnect event asynchronously, after onconnectionavailable.
+  connection->didChangeState(WebPresentationConnectionState::Connected);
+
   return connection;
 }
 
@@ -423,8 +426,8 @@
 
   m_state = state;
   switch (m_state) {
+    // There is no event handler for state changes to Connecting.
     case WebPresentationConnectionState::Connecting:
-      NOTREACHED();
       return;
     case WebPresentationConnectionState::Connected:
       dispatchStateChangeEvent(Event::create(EventTypeNames::connect));
diff --git a/third_party/WebKit/Source/platform/graphics/ImageDecodingStore.cpp b/third_party/WebKit/Source/platform/graphics/ImageDecodingStore.cpp
index 61aa435..a6e589d 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageDecodingStore.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageDecodingStore.cpp
@@ -224,7 +224,7 @@
   typename U::KeyType key = cacheEntry->cacheKey();
   typename V::AddResult result =
       identifierMap->add(cacheEntry->generator(), typename V::MappedType());
-  result.storedValue->value.add(key);
+  result.storedValue->value.insert(key);
   cacheMap->add(key, std::move(cacheEntry));
 
   TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.image_decoding"),
diff --git a/third_party/WebKit/Source/web/tests/FrameThrottlingTest.cpp b/third_party/WebKit/Source/web/tests/FrameThrottlingTest.cpp
index 585b1e8..c9c898fa 100644
--- a/third_party/WebKit/Source/web/tests/FrameThrottlingTest.cpp
+++ b/third_party/WebKit/Source/web/tests/FrameThrottlingTest.cpp
@@ -977,4 +977,25 @@
             innerDiv->layoutObject()->paintProperties()->transform()->matrix());
 }
 
+TEST_F(FrameThrottlingTest, DisplayNoneNotThrottled) {
+  SimRequest mainResource("https://example.com/", "text/html");
+
+  loadURL("https://example.com/");
+  mainResource.complete(
+      "<style>iframe { transform: translateY(480px); }</style>"
+      "<iframe sandbox id=frame></iframe>");
+
+  auto* frameElement = toHTMLIFrameElement(document().getElementById("frame"));
+  auto* frameDocument = frameElement->contentDocument();
+
+  // Initially the frame is throttled as it is offscreen.
+  compositeFrame();
+  EXPECT_TRUE(frameDocument->view()->canThrottleRendering());
+
+  // Setting display:none unthrottles the frame.
+  frameElement->setAttribute(styleAttr, "display: none");
+  compositeFrame();
+  EXPECT_FALSE(frameDocument->view()->canThrottleRendering());
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
index 74884f3..9f48095 100644
--- a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
+++ b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
@@ -65,12 +65,6 @@
     EXPECT_FLOAT_EQ((expected).y(), (actual).y()); \
   } while (false)
 
-#define EXPECT_POINT_EQ(expected, actual)    \
-  do {                                       \
-    EXPECT_EQ((expected).x(), (actual).x()); \
-    EXPECT_EQ((expected).y(), (actual).y()); \
-  } while (false)
-
 #define EXPECT_SIZE_EQ(expected, actual)               \
   do {                                                 \
     EXPECT_EQ((expected).width(), (actual).width());   \
diff --git a/third_party/WebKit/Source/wtf/DequeTest.cpp b/third_party/WebKit/Source/wtf/DequeTest.cpp
index 6751a39..791a5a1 100644
--- a/third_party/WebKit/Source/wtf/DequeTest.cpp
+++ b/third_party/WebKit/Source/wtf/DequeTest.cpp
@@ -288,12 +288,12 @@
 class WrappedInt {
  public:
   WrappedInt(int i = 0) : m_originalThisPtr(this), m_i(i) {
-    constructedWrappedInts.add(this);
+    constructedWrappedInts.insert(this);
   }
 
   WrappedInt(const WrappedInt& other)
       : m_originalThisPtr(this), m_i(other.m_i) {
-    constructedWrappedInts.add(this);
+    constructedWrappedInts.insert(this);
   }
 
   WrappedInt& operator=(const WrappedInt& other) {
diff --git a/third_party/WebKit/Source/wtf/HashSetTest.cpp b/third_party/WebKit/Source/wtf/HashSetTest.cpp
index 72cf6611..a8049ed 100644
--- a/third_party/WebKit/Source/wtf/HashSetTest.cpp
+++ b/third_party/WebKit/Source/wtf/HashSetTest.cpp
@@ -54,7 +54,7 @@
 
   // Adding items up to size should never change the capacity.
   for (size_t i = 0; i < size; ++i) {
-    testSet.add(i + 1);  // Avoid adding '0'.
+    testSet.insert(i + 1);  // Avoid adding '0'.
     EXPECT_EQ(initialCapacity, testSet.capacity());
   }
 
@@ -62,12 +62,12 @@
   // capacity.
   unsigned capacityLimit = initialCapacity / 2 - 1;
   for (size_t i = size; i < capacityLimit; ++i) {
-    testSet.add(i + 1);
+    testSet.insert(i + 1);
     EXPECT_EQ(initialCapacity, testSet.capacity());
   }
 
   // Adding one more item increases the capacity.
-  testSet.add(capacityLimit + 1);
+  testSet.insert(capacityLimit + 1);
   EXPECT_GT(testSet.capacity(), initialCapacity);
 
   testReserveCapacity<size - 1>();
@@ -96,7 +96,7 @@
     // AddResult in a separate scope to avoid assertion hit,
     // since we modify the container further.
     HashSet<std::unique_ptr<Dummy>>::AddResult res1 =
-        set.add(WTF::wrapUnique(ptr1));
+        set.insert(WTF::wrapUnique(ptr1));
     EXPECT_EQ(ptr1, res1.storedValue->get());
   }
 
@@ -109,7 +109,7 @@
   Dummy* ptr2 = new Dummy(deleted2);
   {
     HashSet<std::unique_ptr<Dummy>>::AddResult res2 =
-        set.add(WTF::wrapUnique(ptr2));
+        set.insert(WTF::wrapUnique(ptr2));
     EXPECT_EQ(res2.storedValue->get(), ptr2);
   }
 
@@ -130,8 +130,8 @@
   deleted2 = false;
   {
     OwnPtrSet set;
-    set.add(WTF::makeUnique<Dummy>(deleted1));
-    set.add(WTF::makeUnique<Dummy>(deleted2));
+    set.insert(WTF::makeUnique<Dummy>(deleted1));
+    set.insert(WTF::makeUnique<Dummy>(deleted2));
   }
   EXPECT_TRUE(deleted1);
   EXPECT_TRUE(deleted2);
@@ -144,8 +144,8 @@
   ptr2 = new Dummy(deleted2);
   {
     OwnPtrSet set;
-    set.add(WTF::wrapUnique(ptr1));
-    set.add(WTF::wrapUnique(ptr2));
+    set.insert(WTF::wrapUnique(ptr1));
+    set.insert(WTF::wrapUnique(ptr2));
     ownPtr1 = set.take(ptr1);
     EXPECT_EQ(1UL, set.size());
     ownPtr2 = set.takeAny();
@@ -183,7 +183,7 @@
   RefPtr<DummyRefCounted> ptr = adoptRef(new DummyRefCounted(isDeleted));
   EXPECT_EQ(0, DummyRefCounted::s_refInvokesCount);
   HashSet<RefPtr<DummyRefCounted>> set;
-  set.add(ptr);
+  set.insert(ptr);
   // Referenced only once (to store a copy in the container).
   EXPECT_EQ(1, DummyRefCounted::s_refInvokesCount);
 
@@ -264,7 +264,7 @@
 TEST(HashSetTest, MoveShouldNotMakeCopy) {
   HashSet<CountCopy> set;
   int counter = 0;
-  set.add(CountCopy(&counter));
+  set.insert(CountCopy(&counter));
 
   HashSet<CountCopy> other(set);
   counter = 0;
@@ -351,7 +351,7 @@
   using TheSet = HashSet<MoveOnly>;
   TheSet set;
   {
-    TheSet::AddResult addResult = set.add(MoveOnly(1, 1));
+    TheSet::AddResult addResult = set.insert(MoveOnly(1, 1));
     EXPECT_TRUE(addResult.isNewEntry);
     EXPECT_EQ(1, addResult.storedValue->value());
     EXPECT_EQ(1, addResult.storedValue->id());
@@ -364,7 +364,7 @@
   EXPECT_TRUE(iter == set.end());
 
   for (int i = 2; i < 32; ++i) {
-    TheSet::AddResult addResult = set.add(MoveOnly(i, i));
+    TheSet::AddResult addResult = set.insert(MoveOnly(i, i));
     EXPECT_TRUE(addResult.isNewEntry);
     EXPECT_EQ(i, addResult.storedValue->value());
     EXPECT_EQ(i, addResult.storedValue->id());
@@ -382,7 +382,7 @@
 
   {
     TheSet::AddResult addResult =
-        set.add(MoveOnly(7, 777));  // With different ID for identification.
+        set.insert(MoveOnly(7, 777));  // With different ID for identification.
     EXPECT_FALSE(addResult.isNewEntry);
     EXPECT_EQ(7, addResult.storedValue->value());
     EXPECT_EQ(7, addResult.storedValue->id());
@@ -407,7 +407,7 @@
   Set set;
   int* onePointer = new int(1);
   {
-    Set::AddResult addResult = set.add(Pointer(onePointer));
+    Set::AddResult addResult = set.insert(Pointer(onePointer));
     EXPECT_TRUE(addResult.isNewEntry);
     EXPECT_EQ(onePointer, addResult.storedValue->get());
     EXPECT_EQ(1, **addResult.storedValue);
@@ -422,7 +422,7 @@
 
   // Insert more to cause a rehash.
   for (int i = 2; i < 32; ++i) {
-    Set::AddResult addResult = set.add(Pointer(new int(i)));
+    Set::AddResult addResult = set.insert(Pointer(new int(i)));
     EXPECT_TRUE(addResult.isNewEntry);
     EXPECT_EQ(i, **addResult.storedValue);
   }
@@ -443,7 +443,7 @@
 
   // Re-insert to the deleted slot.
   {
-    Set::AddResult addResult = set.add(std::move(one));
+    Set::AddResult addResult = set.insert(std::move(one));
     EXPECT_TRUE(addResult.isNewEntry);
     EXPECT_EQ(onePointer, addResult.storedValue->get());
     EXPECT_EQ(1, **addResult.storedValue);
@@ -474,9 +474,9 @@
   EXPECT_TRUE(oneTwoThree.contains(3));
 
   // Put some jank so we can check if the assignments later can clear them.
-  empty.add(9999);
-  one.add(9999);
-  oneTwoThree.add(9999);
+  empty.insert(9999);
+  one.insert(9999);
+  oneTwoThree.insert(9999);
 
   empty = {};
   EXPECT_TRUE(empty.isEmpty());
diff --git a/third_party/WebKit/Source/wtf/VectorTest.cpp b/third_party/WebKit/Source/wtf/VectorTest.cpp
index a7ad22a1..2ae71e9e 100644
--- a/third_party/WebKit/Source/wtf/VectorTest.cpp
+++ b/third_party/WebKit/Source/wtf/VectorTest.cpp
@@ -284,12 +284,12 @@
 class WrappedInt {
  public:
   WrappedInt(int i = 0) : m_originalThisPtr(this), m_i(i) {
-    constructedWrappedInts.add(this);
+    constructedWrappedInts.insert(this);
   }
 
   WrappedInt(const WrappedInt& other)
       : m_originalThisPtr(this), m_i(other.m_i) {
-    constructedWrappedInts.add(this);
+    constructedWrappedInts.insert(this);
   }
 
   WrappedInt& operator=(const WrappedInt& other) {
diff --git a/third_party/WebKit/Source/wtf/text/AtomicStringTable.cpp b/third_party/WebKit/Source/wtf/text/AtomicStringTable.cpp
index c5126ab..7ca6f715 100644
--- a/third_party/WebKit/Source/wtf/text/AtomicStringTable.cpp
+++ b/third_party/WebKit/Source/wtf/text/AtomicStringTable.cpp
@@ -188,7 +188,7 @@
   if (!string->length())
     return StringImpl::empty();
 
-  StringImpl* result = *m_table.add(string).storedValue;
+  StringImpl* result = *m_table.insert(string).storedValue;
 
   if (!result->isAtomic())
     result->setIsAtomic(true);
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py
index e053170..7cc468b 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py
@@ -97,7 +97,7 @@
         self.run(['git', 'apply', '-'], input=patch)
         self.run(['git', 'add', '.'])
         self.run(['git', 'commit', '--author', author, '-am', message])
-        self.run(['git', 'push', REMOTE_NAME, self.branch_name])
+        self.run(['git', 'push', '-f', REMOTE_NAME, self.branch_name])
 
         return self.branch_name
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py
index 8591941..1c5c9d26 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py
@@ -98,4 +98,4 @@
             ['git', 'apply', '-'],
             ['git', 'add', '.'],
             ['git', 'commit', '--author', 'author', '-am', 'message'],
-            ['git', 'push', 'github', 'chromium-export-try']])
+            ['git', 'push', '-f', 'github', 'chromium-export-try']])
diff --git a/tools/gn/misc/vim/autoload/gn.vim b/tools/gn/misc/vim/autoload/gn.vim
index c1df012..5573efc0 100644
--- a/tools/gn/misc/vim/autoload/gn.vim
+++ b/tools/gn/misc/vim/autoload/gn.vim
@@ -10,8 +10,17 @@
   let l:new_path = substitute(l:new_path, '\v:.*$', '', '')
 
   " Append 'BUILD.gn', only if this is a directory and not a file
-  if isdirectory(l:new_path)
-    let l:new_path = substitute(l:new_path, '\v/?$', '/BUILD.gn', '')
+  " Prefer using maktaba if it's available, but fallback to an alternative
+  if exists('*maktaba#path#Basename')
+    " Check if the last part of the path appears to be a file
+    if maktaba#path#Basename(l:new_path) !~# '\V.'
+      let l:new_path = maktaba#path#Join([l:new_path, 'BUILD.gn'])
+    endif
+  else
+    " This will break if 'autochdir' is enabled
+    if isdirectory(l:new_path)
+      let l:new_path = substitute(l:new_path, '\v/?$', '/BUILD.gn', '')
+    endif
   endif
   return l:new_path
 endfunction
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 35b3c77..8c8876c4 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -26732,6 +26732,10 @@
 </histogram>
 
 <histogram name="Media.WindowsCoreAudioInput" enum="BooleanSuccess">
+  <obsolete>
+    Deprecated 01/2017 as Windows Core Audio is now the only audio input
+    implementation on Windows.
+  </obsolete>
   <owner>henrika@chromium.org</owner>
   <summary>
     Whether Chrome is using Windows Core Audio for audio input or not. Updated
diff --git a/tools/perf/benchmarks/memory.py b/tools/perf/benchmarks/memory.py
index b0eafac..28c30faa 100644
--- a/tools/perf/benchmarks/memory.py
+++ b/tools/perf/benchmarks/memory.py
@@ -72,12 +72,6 @@
     return False
 
   @classmethod
-  def ShouldDisable(cls, possible_browser):
-    # TODO(crbug.com/586148): Benchmark should not depend on DeskClock app.
-    return not possible_browser.platform.CanLaunchApplication(
-        'com.google.android.deskclock')
-
-  @classmethod
   def ValueCanBeAddedPredicate(cls, value, is_first_result):
     # TODO(crbug.com/610962): Remove this stopgap when the perf dashboard
     # is able to cope with the data load generated by TBMv2 metrics.
diff --git a/tools/perf/benchmarks/system_health.py b/tools/perf/benchmarks/system_health.py
index 75a68813..2b013a5 100644
--- a/tools/perf/benchmarks/system_health.py
+++ b/tools/perf/benchmarks/system_health.py
@@ -105,15 +105,6 @@
     return page_sets.SystemHealthStorySet(platform=self.PLATFORM,
                                           take_memory_measurement=True)
 
-  def SetExtraBrowserOptions(self, options):
-    # Just before we measure memory we flush the system caches
-    # unfortunately this doesn't immediately take effect, instead
-    # the next story run is effected. Due to this the first story run
-    # has anomalous results. This option causes us to flush caches
-    # each time before Chrome starts so we effect even the first story
-    # - avoiding the bug.
-    options.clear_sytem_cache_for_browser_and_profile_on_start = True
-
   @classmethod
   def ShouldTearDownStateAfterEachStoryRun(cls):
     return True
@@ -153,6 +144,15 @@
 
     return possible_browser.platform.GetDeviceTypeName() == 'Desktop'
 
+  def SetExtraBrowserOptions(self, options):
+    # Just before we measure memory we flush the system caches
+    # unfortunately this doesn't immediately take effect, instead
+    # the next story run is effected. Due to this the first story run
+    # has anomalous results. This option causes us to flush caches
+    # each time before Chrome starts so we effect even the first story
+    # - avoiding the bug.
+    options.clear_sytem_cache_for_browser_and_profile_on_start = True
+
 
 @benchmark.Enabled('android-webview')
 class WebviewStartupSystemHealthBenchmark(perf_benchmark.PerfBenchmark):
diff --git a/tools/perf/page_sets/memory_top_10_mobile.py b/tools/perf/page_sets/memory_top_10_mobile.py
index 4a56c8e..ceab901 100644
--- a/tools/perf/page_sets/memory_top_10_mobile.py
+++ b/tools/perf/page_sets/memory_top_10_mobile.py
@@ -8,7 +8,6 @@
 from telemetry.page import shared_page_state
 from telemetry import story
 
-from devil.android.sdk import intent # pylint: disable=import-error
 from devil.android.sdk import keyevent # pylint: disable=import-error
 
 from page_sets import top_10_mobile
@@ -51,17 +50,15 @@
     action_runner.tab.WaitForDocumentReadyStateToBeComplete()
 
     # Launch clock app, pushing Chrome to the background.
-    android_platform = action_runner.tab.browser.platform
-    android_platform.LaunchAndroidApplication(
-        intent.Intent(package='com.google.android.deskclock',
-                      activity='com.android.deskclock.DeskClock'),
-        app_has_webviews=False)
+    android_browser = action_runner.tab.browser
+    android_browser.Background()
 
     # Take measurement.
     action_runner.MeasureMemory(self.story_set.DETERMINISTIC_MODE)
 
     # Go back to Chrome.
-    android_platform.android_action_runner.InputKeyEvent(keyevent.KEYCODE_BACK)
+    android_browser.platform.android_action_runner.InputKeyEvent(
+        keyevent.KEYCODE_BACK)
 
 
 class MemoryTop10Mobile(story.StorySet):
diff --git a/ui/aura/mus/window_manager_delegate.h b/ui/aura/mus/window_manager_delegate.h
index 87f907a..4f5f137 100644
--- a/ui/aura/mus/window_manager_delegate.h
+++ b/ui/aura/mus/window_manager_delegate.h
@@ -94,6 +94,10 @@
       const std::string& name,
       std::unique_ptr<std::vector<uint8_t>>* new_data) = 0;
 
+  // A client requested to change focusibility of |window|. We currently assume
+  // this always succeeds.
+  virtual void OnWmSetCanFocus(Window* window, bool can_focus) = 0;
+
   // A client has requested a new top level window. The delegate should create
   // and parent the window appropriately and return it. |properties| is the
   // supplied properties from the client requesting the new window. The
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc
index 0ae7b855..743f1a0 100644
--- a/ui/aura/mus/window_tree_client.cc
+++ b/ui/aura/mus/window_tree_client.cc
@@ -1422,6 +1422,12 @@
     window_manager_internal_client_->WmResponse(change_id, result);
 }
 
+void WindowTreeClient::WmSetCanFocus(Id window_id, bool can_focus) {
+  WindowMus* window = GetWindowByServerId(window_id);
+  if (window)
+    window_manager_delegate_->OnWmSetCanFocus(window->GetWindow(), can_focus);
+}
+
 void WindowTreeClient::WmCreateTopLevelWindow(
     uint32_t change_id,
     ClientSpecificId requesting_client_id,
@@ -1510,6 +1516,43 @@
   window_manager_delegate_->OnWmDeactivateWindow(window->GetWindow());
 }
 
+void WindowTreeClient::WmStackAbove(uint32_t wm_change_id, Id above_id,
+                                    Id below_id) {
+  if (!window_manager_delegate_)
+    return;
+
+  WindowMus* below_mus = GetWindowByServerId(below_id);
+  if (!below_mus) {
+    DVLOG(1) << "Attempt to stack at top invalid window " << below_id;
+    if (window_manager_internal_client_)
+      window_manager_internal_client_->WmResponse(wm_change_id, false);
+    return;
+  }
+
+  WindowMus* above_mus = GetWindowByServerId(above_id);
+  if (!above_mus) {
+    DVLOG(1) << "Attempt to stack at top invalid window " << above_id;
+    if (window_manager_internal_client_)
+      window_manager_internal_client_->WmResponse(wm_change_id, false);
+    return;
+  }
+
+  Window* above = above_mus->GetWindow();
+  Window* below = below_mus->GetWindow();
+
+  if (above->parent() != below->parent()) {
+    DVLOG(1) << "Windows do not share the same parent";
+    if (window_manager_internal_client_)
+      window_manager_internal_client_->WmResponse(wm_change_id, false);
+    return;
+  }
+
+  above->parent()->StackChildAbove(above, below);
+
+  if (window_manager_internal_client_)
+    window_manager_internal_client_->WmResponse(wm_change_id, true);
+}
+
 void WindowTreeClient::WmStackAtTop(uint32_t wm_change_id, uint32_t window_id) {
   if (!window_manager_delegate_)
     return;
@@ -1655,6 +1698,16 @@
       WindowMus::Get(window_tree_host->window())->server_id());
 }
 
+void WindowTreeClient::OnWindowTreeHostStackAbove(
+    WindowTreeHostMus* window_tree_host,
+    Window* window) {
+  WindowMus* above = WindowMus::Get(window_tree_host->window());
+  WindowMus* below = WindowMus::Get(window);
+  const uint32_t change_id = ScheduleInFlightChange(
+      base::MakeUnique<CrashInFlightChange>(above, ChangeType::REORDER));
+  tree_->StackAbove(change_id, above->server_id(), below->server_id());
+}
+
 void WindowTreeClient::OnWindowTreeHostStackAtTop(
     WindowTreeHostMus* window_tree_host) {
   WindowMus* window = WindowMus::Get(window_tree_host->window());
diff --git a/ui/aura/mus/window_tree_client.h b/ui/aura/mus/window_tree_client.h
index f2bf77d2..403de5c 100644
--- a/ui/aura/mus/window_tree_client.h
+++ b/ui/aura/mus/window_tree_client.h
@@ -396,6 +396,7 @@
       Id window_id,
       const std::string& name,
       const base::Optional<std::vector<uint8_t>>& transit_data) override;
+  void WmSetCanFocus(Id window_id, bool can_focus) override;
   void WmCreateTopLevelWindow(
       uint32_t change_id,
       ClientSpecificId requesting_client_id,
@@ -409,6 +410,7 @@
                          const gfx::Point& cursor_location) override;
   void WmCancelMoveLoop(uint32_t window_id) override;
   void WmDeactivateWindow(Id window_id) override;
+  void WmStackAbove(uint32_t change_id, Id above_id, Id below_id) override;
   void WmStackAtTop(uint32_t change_id, uint32_t window_id) override;
   void OnAccelerator(uint32_t ack_id,
                      uint32_t accelerator_id,
@@ -442,6 +444,8 @@
       const base::Optional<gfx::Rect>& mask_rect) override;
   void OnWindowTreeHostDeactivateWindow(
       WindowTreeHostMus* window_tree_host) override;
+  void OnWindowTreeHostStackAbove(WindowTreeHostMus* window_tree_host,
+                                  Window* window) override;
   void OnWindowTreeHostStackAtTop(WindowTreeHostMus* window_tree_host) override;
   std::unique_ptr<WindowPortMus> CreateWindowPortForTopLevel(
       const std::map<std::string, std::vector<uint8_t>>* properties) override;
diff --git a/ui/aura/mus/window_tree_host_mus.cc b/ui/aura/mus/window_tree_host_mus.cc
index 2f5497cb..820702a 100644
--- a/ui/aura/mus/window_tree_host_mus.cc
+++ b/ui/aura/mus/window_tree_host_mus.cc
@@ -149,6 +149,10 @@
   delegate_->OnWindowTreeHostDeactivateWindow(this);
 }
 
+void WindowTreeHostMus::StackAbove(Window* window) {
+  delegate_->OnWindowTreeHostStackAbove(this, window);
+}
+
 void WindowTreeHostMus::StackAtTop() {
   delegate_->OnWindowTreeHostStackAtTop(this);
 }
diff --git a/ui/aura/mus/window_tree_host_mus.h b/ui/aura/mus/window_tree_host_mus.h
index af10e05..f028bd2 100644
--- a/ui/aura/mus/window_tree_host_mus.h
+++ b/ui/aura/mus/window_tree_host_mus.h
@@ -75,6 +75,10 @@
   // Requests that the window manager change the activation to the next window.
   void DeactivateWindow();
 
+  // Requests that our root window be stacked above this other root window
+  // which our connection owns.
+  void StackAbove(Window* window);
+
   // Requests that our root window be stacked above all other parallel root
   // windows which we might not own.
   void StackAtTop();
diff --git a/ui/aura/mus/window_tree_host_mus_delegate.h b/ui/aura/mus/window_tree_host_mus_delegate.h
index b25416d..1d4d0113 100644
--- a/ui/aura/mus/window_tree_host_mus_delegate.h
+++ b/ui/aura/mus/window_tree_host_mus_delegate.h
@@ -46,6 +46,11 @@
   virtual void OnWindowTreeHostDeactivateWindow(
       WindowTreeHostMus* window_tree_host) = 0;
 
+  // Called to stack the native window above the native window of |window|.
+  virtual void OnWindowTreeHostStackAbove(
+      WindowTreeHostMus* window_tree_host,
+      Window* window) = 0;
+
   // Called to stack the native window above other native windows.
   virtual void OnWindowTreeHostStackAtTop(
       WindowTreeHostMus* window_tree_host) = 0;
diff --git a/ui/aura/test/aura_test_base.cc b/ui/aura/test/aura_test_base.cc
index e914efd..e1325b78 100644
--- a/ui/aura/test/aura_test_base.cc
+++ b/ui/aura/test/aura_test_base.cc
@@ -169,6 +169,8 @@
   return true;
 }
 
+void AuraTestBase::OnWmSetCanFocus(Window* window, bool can_focus) {}
+
 Window* AuraTestBase::OnWmCreateTopLevelWindow(
     ui::mojom::WindowType window_type,
     std::map<std::string, std::vector<uint8_t>>* properties) {
diff --git a/ui/aura/test/aura_test_base.h b/ui/aura/test/aura_test_base.h
index 3e3a823..1f690c6d 100644
--- a/ui/aura/test/aura_test_base.h
+++ b/ui/aura/test/aura_test_base.h
@@ -102,6 +102,7 @@
       Window* window,
       const std::string& name,
       std::unique_ptr<std::vector<uint8_t>>* new_data) override;
+  void OnWmSetCanFocus(Window* window, bool can_focus) override;
   Window* OnWmCreateTopLevelWindow(
       ui::mojom::WindowType window_type,
       std::map<std::string, std::vector<uint8_t>>* properties) override;
diff --git a/ui/aura/test/mus/test_window_tree.cc b/ui/aura/test/mus/test_window_tree.cc
index 12f94b54..6245a04 100644
--- a/ui/aura/test/mus/test_window_tree.cc
+++ b/ui/aura/test/mus/test_window_tree.cc
@@ -268,6 +268,9 @@
 
 void TestWindowTree::DeactivateWindow(uint32_t window_id) {}
 
+void TestWindowTree::StackAbove(uint32_t change_id, uint32_t above_id,
+                                uint32_t below_id) {}
+
 void TestWindowTree::StackAtTop(uint32_t change_id, uint32_t window_id) {}
 
 void TestWindowTree::GetWindowManagerClient(
diff --git a/ui/aura/test/mus/test_window_tree.h b/ui/aura/test/mus/test_window_tree.h
index cf0e403ef..aba306a 100644
--- a/ui/aura/test/mus/test_window_tree.h
+++ b/ui/aura/test/mus/test_window_tree.h
@@ -177,6 +177,8 @@
   void OnWindowInputEventAck(uint32_t event_id,
                              ui::mojom::EventResult result) override;
   void DeactivateWindow(uint32_t window_id) override;
+  void StackAbove(uint32_t change_id, uint32_t above_id,
+                  uint32_t below_id) override;
   void StackAtTop(uint32_t change_id, uint32_t window_id) override;
   void GetWindowManagerClient(
       mojo::AssociatedInterfaceRequest<ui::mojom::WindowManagerClient> internal)
diff --git a/ui/events/cocoa/events_mac.mm b/ui/events/cocoa/events_mac.mm
index 29b7fc9..efcf3a4 100644
--- a/ui/events/cocoa/events_mac.mm
+++ b/ui/events/cocoa/events_mac.mm
@@ -89,11 +89,7 @@
   return timestamp;
 }
 
-gfx::Point EventLocationFromNative(const base::NativeEvent& native_event) {
-  return gfx::ToFlooredPoint(EventLocationFromNativeF(native_event));
-}
-
-gfx::PointF EventLocationFromNativeF(const base::NativeEvent& native_event) {
+gfx::PointF EventLocationFromNative(const base::NativeEvent& native_event) {
   NSWindow* window = [native_event window];
   if (!window) {
     NOTIMPLEMENTED();  // Point will be in screen coordinates.
diff --git a/ui/events/cocoa/events_mac_unittest.mm b/ui/events/cocoa/events_mac_unittest.mm
index 30986ee..4fb6b62cc 100644
--- a/ui/events/cocoa/events_mac_unittest.mm
+++ b/ui/events/cocoa/events_mac_unittest.mm
@@ -215,33 +215,25 @@
       TestMouseEvent(kCGEventLeftMouseDown, location, kNoEventFlags);
   EXPECT_EQ(ui::ET_MOUSE_PRESSED, ui::EventTypeFromNative(event));
   EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, ui::EventFlagsFromNative(event));
-  EXPECT_EQ(location, ui::EventLocationFromNative(event));
-  EXPECT_EQ(ui::EventLocationFromNative(event),
-            gfx::ToFlooredPoint(ui::EventLocationFromNativeF(event)));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(event)));
 
   event =
       TestMouseEvent(kCGEventOtherMouseDown, location, kCGEventFlagMaskShift);
   EXPECT_EQ(ui::ET_MOUSE_PRESSED, ui::EventTypeFromNative(event));
   EXPECT_EQ(ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_SHIFT_DOWN,
             ui::EventFlagsFromNative(event));
-  EXPECT_EQ(location, ui::EventLocationFromNative(event));
-  EXPECT_EQ(ui::EventLocationFromNative(event),
-            gfx::ToFlooredPoint(ui::EventLocationFromNativeF(event)));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(event)));
 
   event = TestMouseEvent(kCGEventRightMouseUp, location, kNoEventFlags);
   EXPECT_EQ(ui::ET_MOUSE_RELEASED, ui::EventTypeFromNative(event));
   EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, ui::EventFlagsFromNative(event));
-  EXPECT_EQ(location, ui::EventLocationFromNative(event));
-  EXPECT_EQ(ui::EventLocationFromNative(event),
-            gfx::ToFlooredPoint(ui::EventLocationFromNativeF(event)));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(event)));
 
   // Scroll up.
   event = TestScrollEvent(location, 0, 1);
   EXPECT_EQ(ui::ET_SCROLL, ui::EventTypeFromNative(event));
   EXPECT_EQ(0, ui::EventFlagsFromNative(event));
-  EXPECT_EQ(location.ToString(), ui::EventLocationFromNative(event).ToString());
-  EXPECT_EQ(ui::EventLocationFromNative(event),
-            gfx::ToFlooredPoint(ui::EventLocationFromNativeF(event)));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(event)));
   offset = ui::GetMouseWheelOffset(event);
   EXPECT_GT(offset.y(), 0);
   EXPECT_EQ(0, offset.x());
@@ -250,9 +242,7 @@
   event = TestScrollEvent(location, 0, -1);
   EXPECT_EQ(ui::ET_SCROLL, ui::EventTypeFromNative(event));
   EXPECT_EQ(0, ui::EventFlagsFromNative(event));
-  EXPECT_EQ(location, ui::EventLocationFromNative(event));
-  EXPECT_EQ(ui::EventLocationFromNative(event),
-            gfx::ToFlooredPoint(ui::EventLocationFromNativeF(event)));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(event)));
   offset = ui::GetMouseWheelOffset(event);
   EXPECT_LT(offset.y(), 0);
   EXPECT_EQ(0, offset.x());
@@ -261,9 +251,7 @@
   event = TestScrollEvent(location, 1, 0);
   EXPECT_EQ(ui::ET_SCROLL, ui::EventTypeFromNative(event));
   EXPECT_EQ(0, ui::EventFlagsFromNative(event));
-  EXPECT_EQ(location, ui::EventLocationFromNative(event));
-  EXPECT_EQ(ui::EventLocationFromNative(event),
-            gfx::ToFlooredPoint(ui::EventLocationFromNativeF(event)));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(event)));
   offset = ui::GetMouseWheelOffset(event);
   EXPECT_EQ(0, offset.y());
   EXPECT_GT(offset.x(), 0);
@@ -272,9 +260,7 @@
   event = TestScrollEvent(location, -1, 0);
   EXPECT_EQ(ui::ET_SCROLL, ui::EventTypeFromNative(event));
   EXPECT_EQ(0, ui::EventFlagsFromNative(event));
-  EXPECT_EQ(location, ui::EventLocationFromNative(event));
-  EXPECT_EQ(ui::EventLocationFromNative(event),
-            gfx::ToFlooredPoint(ui::EventLocationFromNativeF(event)));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(event)));
   offset = ui::GetMouseWheelOffset(event);
   EXPECT_EQ(0, offset.y());
   EXPECT_LT(offset.x(), 0);
@@ -296,7 +282,7 @@
       TestMouseEvent(kCGEventLeftMouseDown, location, kNoEventFlags);
   EXPECT_EQ(ui::ET_MOUSE_PRESSED, ui::EventTypeFromNative(event));
   EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, ui::EventFlagsFromNative(event));
-  EXPECT_EQ(location, ui::EventLocationFromNative(event));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(event)));
 
   // And be explicit, to ensure the test doesn't depend on some property of the
   // test harness. The change to the frame rect could be OS-specfic, so set it
@@ -315,7 +301,8 @@
                            clickCount:0
                              pressure:1.0];
   // Bottom-left corner should be flipped.
-  EXPECT_EQ(gfx::Point(0, kTestHeight), ui::EventLocationFromNative(event));
+  EXPECT_EQ(gfx::Point(0, kTestHeight),
+            gfx::ToFlooredPoint(ui::EventLocationFromNative(event)));
 
   // Removing the border, and sending the same event should move it down in the
   // toolkit-views coordinate system.
@@ -324,7 +311,7 @@
   [test_window() setStyleMask:NSBorderlessWindowMask];
   [test_window() setFrame:frame_rect display:YES];
   EXPECT_EQ(gfx::Point(0, kTestHeight + height_change),
-            ui::EventLocationFromNative(event));
+            gfx::ToFlooredPoint(ui::EventLocationFromNative(event)));
 }
 
 // Testing for ui::EventTypeFromNative() not covered by ButtonEvents.
diff --git a/ui/events/event.cc b/ui/events/event.cc
index a5fe95a..879f3e1 100644
--- a/ui/events/event.cc
+++ b/ui/events/event.cc
@@ -479,7 +479,7 @@
     : Event(native_event,
             EventTypeFromNative(native_event),
             EventFlagsFromNative(native_event)),
-      location_(EventLocationFromNativeF(native_event)),
+      location_(EventLocationFromNative(native_event)),
       root_location_(location_) {}
 
 LocatedEvent::LocatedEvent(EventType type,
diff --git a/ui/events/event_utils.h b/ui/events/event_utils.h
index f1109a8..0d61f8d 100644
--- a/ui/events/event_utils.h
+++ b/ui/events/event_utils.h
@@ -67,10 +67,7 @@
 // |Point| has the origin at top-left of the "root window".  The nature of
 // this "root window" and how it maps to platform-specific drawing surfaces is
 // defined in ui/aura/root_window.* and ui/aura/window_tree_host*.
-// TODO(tdresser): Return gfx::PointF here. See crbug.com/337827.
-EVENTS_EXPORT gfx::Point EventLocationFromNative(
-    const base::NativeEvent& native_event);
-EVENTS_EXPORT gfx::PointF EventLocationFromNativeF(
+EVENTS_EXPORT gfx::PointF EventLocationFromNative(
     const base::NativeEvent& native_event);
 
 // Gets the location in native system coordinate space.
diff --git a/ui/events/events_default.cc b/ui/events/events_default.cc
index 2d2b682..8182b4a 100644
--- a/ui/events/events_default.cc
+++ b/ui/events/events_default.cc
@@ -32,11 +32,7 @@
   return e->location();
 }
 
-gfx::Point EventLocationFromNative(const base::NativeEvent& native_event) {
-  return EventSystemLocationFromNative(native_event);
-}
-
-gfx::PointF EventLocationFromNativeF(const base::NativeEvent& native_event) {
+gfx::PointF EventLocationFromNative(const base::NativeEvent& native_event) {
   const ui::LocatedEvent* e =
       static_cast<const ui::LocatedEvent*>(native_event);
   DCHECK(e->IsMouseEvent() || e->IsTouchEvent() || e->IsGestureEvent() ||
diff --git a/ui/events/events_stub.cc b/ui/events/events_stub.cc
index 7ca30e0..4672467 100644
--- a/ui/events/events_stub.cc
+++ b/ui/events/events_stub.cc
@@ -32,12 +32,7 @@
   return base::TimeTicks();
 }
 
-gfx::Point EventLocationFromNative(const base::NativeEvent& native_event) {
-  NOTIMPLEMENTED();
-  return gfx::Point();
-}
-
-gfx::PointF EventLocationFromNativeF(const base::NativeEvent& native_event) {
+gfx::PointF EventLocationFromNative(const base::NativeEvent& native_event) {
   NOTIMPLEMENTED();
   return gfx::PointF();
 }
diff --git a/ui/events/win/events_win.cc b/ui/events/win/events_win.cc
index 89a1cfd..f39e3510 100644
--- a/ui/events/win/events_win.cc
+++ b/ui/events/win/events_win.cc
@@ -229,7 +229,7 @@
   return EventTimeForNow();
 }
 
-gfx::Point EventLocationFromNative(const base::NativeEvent& native_event) {
+gfx::PointF EventLocationFromNative(const base::NativeEvent& native_event) {
   POINT native_point;
   if ((native_event.message == WM_MOUSELEAVE ||
        native_event.message == WM_NCMOUSELEAVE) ||
@@ -242,7 +242,7 @@
     // Note: Wheel events are considered client, but their position is in screen
     //       coordinates.
     // Client message. The position is contained in the LPARAM.
-    return gfx::Point(native_event.lParam);
+    return gfx::PointF(gfx::Point(native_event.lParam));
   } else {
     DCHECK(IsNonClientMouseEvent(native_event) ||
            IsMouseWheelEvent(native_event) || IsScrollEvent(native_event));
@@ -252,11 +252,7 @@
     native_point.y = GET_Y_LPARAM(native_event.lParam);
   }
   ScreenToClient(native_event.hwnd, &native_point);
-  return gfx::Point(native_point);
-}
-
-gfx::PointF EventLocationFromNativeF(const base::NativeEvent& native_event) {
-  return gfx::PointF(EventLocationFromNative(native_event));
+  return gfx::PointF(gfx::Point(native_point));
 }
 
 gfx::Point EventSystemLocationFromNative(
diff --git a/ui/events/x/events_x.cc b/ui/events/x/events_x.cc
index 78152b45..2160650 100644
--- a/ui/events/x/events_x.cc
+++ b/ui/events/x/events_x.cc
@@ -90,12 +90,8 @@
   return timestamp;
 }
 
-gfx::Point EventLocationFromNative(const base::NativeEvent& native_event) {
-  return EventLocationFromXEvent(*native_event);
-}
-
-gfx::PointF EventLocationFromNativeF(const base::NativeEvent& native_event) {
-  return gfx::PointF(EventLocationFromNative(native_event));
+gfx::PointF EventLocationFromNative(const base::NativeEvent& native_event) {
+  return gfx::PointF(EventLocationFromXEvent(*native_event));
 }
 
 gfx::Point EventSystemLocationFromNative(
diff --git a/ui/events/x/events_x_unittest.cc b/ui/events/x/events_x_unittest.cc
index 529e59a..6e77c97 100644
--- a/ui/events/x/events_x_unittest.cc
+++ b/ui/events/x/events_x_unittest.cc
@@ -101,7 +101,7 @@
   EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, ui::EventFlagsFromNative(&event));
   EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON,
             ui::GetChangedMouseButtonFlagsFromNative(&event));
-  EXPECT_EQ(location, ui::EventLocationFromNative(&event));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(&event)));
 
   InitButtonEvent(&event, true, location, 2, Button1Mask | ShiftMask);
   EXPECT_EQ(ui::ET_MOUSE_PRESSED, ui::EventTypeFromNative(&event));
@@ -110,21 +110,21 @@
             ui::EventFlagsFromNative(&event));
   EXPECT_EQ(ui::EF_MIDDLE_MOUSE_BUTTON,
             ui::GetChangedMouseButtonFlagsFromNative(&event));
-  EXPECT_EQ(location, ui::EventLocationFromNative(&event));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(&event)));
 
   InitButtonEvent(&event, false, location, 3, 0);
   EXPECT_EQ(ui::ET_MOUSE_RELEASED, ui::EventTypeFromNative(&event));
   EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, ui::EventFlagsFromNative(&event));
   EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON,
             ui::GetChangedMouseButtonFlagsFromNative(&event));
-  EXPECT_EQ(location, ui::EventLocationFromNative(&event));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(&event)));
 
   // Scroll up.
   InitButtonEvent(&event, true, location, 4, 0);
   EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(&event));
   EXPECT_EQ(0, ui::EventFlagsFromNative(&event));
   EXPECT_EQ(ui::EF_NONE, ui::GetChangedMouseButtonFlagsFromNative(&event));
-  EXPECT_EQ(location, ui::EventLocationFromNative(&event));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(&event)));
   offset = ui::GetMouseWheelOffset(&event);
   EXPECT_GT(offset.y(), 0);
   EXPECT_EQ(0, offset.x());
@@ -134,7 +134,7 @@
   EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(&event));
   EXPECT_EQ(0, ui::EventFlagsFromNative(&event));
   EXPECT_EQ(ui::EF_NONE, ui::GetChangedMouseButtonFlagsFromNative(&event));
-  EXPECT_EQ(location, ui::EventLocationFromNative(&event));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(&event)));
   offset = ui::GetMouseWheelOffset(&event);
   EXPECT_LT(offset.y(), 0);
   EXPECT_EQ(0, offset.x());
@@ -144,7 +144,7 @@
   EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(&event));
   EXPECT_EQ(0, ui::EventFlagsFromNative(&event));
   EXPECT_EQ(ui::EF_NONE, ui::GetChangedMouseButtonFlagsFromNative(&event));
-  EXPECT_EQ(location, ui::EventLocationFromNative(&event));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(&event)));
   offset = ui::GetMouseWheelOffset(&event);
   EXPECT_EQ(0, offset.y());
   EXPECT_GT(offset.x(), 0);
@@ -154,7 +154,7 @@
   EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(&event));
   EXPECT_EQ(0, ui::EventFlagsFromNative(&event));
   EXPECT_EQ(ui::EF_NONE, ui::GetChangedMouseButtonFlagsFromNative(&event));
-  EXPECT_EQ(location, ui::EventLocationFromNative(&event));
+  EXPECT_EQ(location, gfx::ToFlooredPoint(ui::EventLocationFromNative(&event)));
   offset = ui::GetMouseWheelOffset(&event);
   EXPECT_EQ(0, offset.y());
   EXPECT_LT(offset.x(), 0);
@@ -189,7 +189,9 @@
   // the way views handle mouse enter. See comments for EnterNotify case in
   // ui::EventTypeFromNative for more details.
   EXPECT_EQ(ui::ET_MOUSE_MOVED, ui::EventTypeFromNative(&event));
-  EXPECT_EQ("10,20", ui::EventLocationFromNative(&event).ToString());
+  EXPECT_EQ(
+      "10,20",
+      gfx::ToFlooredPoint(ui::EventLocationFromNative(&event)).ToString());
   EXPECT_EQ("110,120", ui::EventSystemLocationFromNative(&event).ToString());
 
   event.xcrossing.type = LeaveNotify;
@@ -198,7 +200,9 @@
   event.xcrossing.x_root = 230;
   event.xcrossing.y_root = 240;
   EXPECT_EQ(ui::ET_MOUSE_EXITED, ui::EventTypeFromNative(&event));
-  EXPECT_EQ("30,40", ui::EventLocationFromNative(&event).ToString());
+  EXPECT_EQ(
+      "30,40",
+      gfx::ToFlooredPoint(ui::EventLocationFromNative(&event)).ToString());
   EXPECT_EQ("230,240", ui::EventSystemLocationFromNative(&event).ToString());
 }
 
@@ -243,9 +247,9 @@
   scoped_xevent.InitTouchEvent(
       0, XI_TouchBegin, 5, gfx::Point(10, 10), valuators);
   EXPECT_EQ(ui::ET_TOUCH_PRESSED, ui::EventTypeFromNative(scoped_xevent));
-  EXPECT_EQ("10,10", ui::EventLocationFromNative(scoped_xevent).ToString());
-  EXPECT_EQ(ui::EventLocationFromNative(scoped_xevent),
-            gfx::ToFlooredPoint(ui::EventLocationFromNativeF(scoped_xevent)));
+  EXPECT_EQ("10,10",
+            gfx::ToFlooredPoint(ui::EventLocationFromNative(scoped_xevent))
+                .ToString());
   EXPECT_EQ(GetTouchId(scoped_xevent), 0);
   EXPECT_FLOAT_EQ(GetTouchAngle(scoped_xevent), 0.15f);
   PointerDetails pointer_details =
@@ -260,9 +264,9 @@
   scoped_xevent.InitTouchEvent(
       0, XI_TouchUpdate, 5, gfx::Point(20, 20), valuators);
   EXPECT_EQ(ui::ET_TOUCH_MOVED, ui::EventTypeFromNative(scoped_xevent));
-  EXPECT_EQ("20,20", ui::EventLocationFromNative(scoped_xevent).ToString());
-  EXPECT_EQ(ui::EventLocationFromNative(scoped_xevent),
-            gfx::ToFlooredPoint(ui::EventLocationFromNativeF(scoped_xevent)));
+  EXPECT_EQ("20,20",
+            gfx::ToFlooredPoint(ui::EventLocationFromNative(scoped_xevent))
+                .ToString());
   EXPECT_EQ(GetTouchId(scoped_xevent), 0);
   EXPECT_FLOAT_EQ(GetTouchAngle(scoped_xevent), 0.25f);
   pointer_details = GetTouchPointerDetailsFromNative(scoped_xevent);
@@ -278,9 +282,9 @@
   scoped_xevent.InitTouchEvent(
       0, XI_TouchBegin, 6, gfx::Point(200, 200), valuators);
   EXPECT_EQ(ui::ET_TOUCH_PRESSED, ui::EventTypeFromNative(scoped_xevent));
-  EXPECT_EQ("200,200", ui::EventLocationFromNative(scoped_xevent).ToString());
-  EXPECT_EQ(ui::EventLocationFromNative(scoped_xevent),
-            gfx::ToFlooredPoint(ui::EventLocationFromNativeF(scoped_xevent)));
+  EXPECT_EQ("200,200",
+            gfx::ToFlooredPoint(ui::EventLocationFromNative(scoped_xevent))
+                .ToString());
   EXPECT_EQ(GetTouchId(scoped_xevent), 1);
   EXPECT_FLOAT_EQ(GetTouchAngle(scoped_xevent), 0.45f);
   pointer_details = GetTouchPointerDetailsFromNative(scoped_xevent);
@@ -294,9 +298,9 @@
   scoped_xevent.InitTouchEvent(
       0, XI_TouchEnd, 5, gfx::Point(30, 30), valuators);
   EXPECT_EQ(ui::ET_TOUCH_RELEASED, ui::EventTypeFromNative(scoped_xevent));
-  EXPECT_EQ("30,30", ui::EventLocationFromNative(scoped_xevent).ToString());
-  EXPECT_EQ(ui::EventLocationFromNative(scoped_xevent),
-            gfx::ToFlooredPoint(ui::EventLocationFromNativeF(scoped_xevent)));
+  EXPECT_EQ("30,30",
+            gfx::ToFlooredPoint(ui::EventLocationFromNative(scoped_xevent))
+                .ToString());
   EXPECT_EQ(GetTouchId(scoped_xevent), 0);
   EXPECT_FLOAT_EQ(GetTouchAngle(scoped_xevent), 0.25f);
   pointer_details = GetTouchPointerDetailsFromNative(scoped_xevent);
@@ -310,9 +314,9 @@
   scoped_xevent.InitTouchEvent(
       0, XI_TouchEnd, 6, gfx::Point(200, 200), valuators);
   EXPECT_EQ(ui::ET_TOUCH_RELEASED, ui::EventTypeFromNative(scoped_xevent));
-  EXPECT_EQ("200,200", ui::EventLocationFromNative(scoped_xevent).ToString());
-  EXPECT_EQ(ui::EventLocationFromNative(scoped_xevent),
-            gfx::ToFlooredPoint(ui::EventLocationFromNativeF(scoped_xevent)));
+  EXPECT_EQ("200,200",
+            gfx::ToFlooredPoint(ui::EventLocationFromNative(scoped_xevent))
+                .ToString());
   EXPECT_EQ(GetTouchId(scoped_xevent), 1);
   EXPECT_FLOAT_EQ(GetTouchAngle(scoped_xevent), 0.45f);
   pointer_details = GetTouchPointerDetailsFromNative(scoped_xevent);
diff --git a/ui/gfx/color_space.cc b/ui/gfx/color_space.cc
index 2bf317b..9a307ddb 100644
--- a/ui/gfx/color_space.cc
+++ b/ui/gfx/color_space.cc
@@ -13,6 +13,26 @@
 
 namespace gfx {
 
+namespace {
+
+SkColorSpaceTransferFn InvertTransferFn(SkColorSpaceTransferFn fn) {
+  SkColorSpaceTransferFn fn_inv = {0};
+  if (fn.fA > 0 && fn.fG > 0) {
+    double a_to_the_g = pow(fn.fA, fn.fG);
+    fn_inv.fA = 1.f / a_to_the_g;
+    fn_inv.fB = -fn.fE / a_to_the_g;
+    fn_inv.fG = 1.f / fn.fG;
+  }
+  fn_inv.fD = fn.fC * fn.fD + fn.fF;
+  fn_inv.fE = -fn.fB / fn.fA;
+  if (fn.fC != 0) {
+    fn_inv.fC = 1.f / fn.fC;
+    fn_inv.fF = -fn.fF / fn.fC;
+  }
+  return fn_inv;
+}
+};
+
 ColorSpace::PrimaryID ColorSpace::PrimaryIDFromInt(int primary_id) {
   if (primary_id < 0 || primary_id > static_cast<int>(PrimaryID::LAST))
     return PrimaryID::UNKNOWN;
@@ -41,6 +61,7 @@
 }
 
 ColorSpace::ColorSpace() {
+  memset(custom_transfer_params_, 0, sizeof(custom_transfer_params_));
   memset(custom_primary_matrix_, 0, sizeof(custom_primary_matrix_));
 }
 
@@ -52,8 +73,8 @@
       transfer_(transfer),
       matrix_(matrix),
       range_(range) {
+  memset(custom_transfer_params_, 0, sizeof(custom_transfer_params_));
   memset(custom_primary_matrix_, 0, sizeof(custom_primary_matrix_));
-  // TODO: Set profile_id_
 }
 
 ColorSpace::ColorSpace(int primaries, int transfer, int matrix, RangeID range)
@@ -61,8 +82,8 @@
       transfer_(TransferIDFromInt(transfer)),
       matrix_(MatrixIDFromInt(matrix)),
       range_(range) {
+  memset(custom_transfer_params_, 0, sizeof(custom_transfer_params_));
   memset(custom_primary_matrix_, 0, sizeof(custom_primary_matrix_));
-  // TODO: Set profile_id_
 }
 
 ColorSpace::ColorSpace(const ColorSpace& other)
@@ -72,6 +93,8 @@
       range_(other.range_),
       icc_profile_id_(other.icc_profile_id_),
       sk_color_space_(other.sk_color_space_) {
+  memcpy(custom_transfer_params_, other.custom_transfer_params_,
+         sizeof(custom_transfer_params_));
   memcpy(custom_primary_matrix_, other.custom_primary_matrix_,
          sizeof(custom_primary_matrix_));
 }
@@ -124,6 +147,10 @@
       memcmp(custom_primary_matrix_, other.custom_primary_matrix_,
              sizeof(custom_primary_matrix_)))
     return false;
+  if (transfer_ == TransferID::CUSTOM &&
+      memcmp(custom_transfer_params_, other.custom_transfer_params_,
+             sizeof(custom_transfer_params_)))
+    return false;
   return true;
 }
 
@@ -162,6 +189,15 @@
     if (primary_result > 0)
       return false;
   }
+  if (transfer_ == TransferID::CUSTOM) {
+    int transfer_result =
+        memcmp(custom_transfer_params_, other.custom_transfer_params_,
+               sizeof(custom_transfer_params_));
+    if (transfer_result < 0)
+      return true;
+    if (transfer_result > 0)
+      return false;
+  }
   return false;
 }
 
@@ -180,4 +216,221 @@
   return icc_profile.GetColorSpace();
 }
 
+void ColorSpace::GetPrimaryMatrix(SkMatrix44* to_XYZD50) const {
+  SkColorSpacePrimaries primaries = {0};
+  switch (primaries_) {
+    case ColorSpace::PrimaryID::CUSTOM:
+      to_XYZD50->set3x3RowMajorf(custom_primary_matrix_);
+      return;
+
+    case ColorSpace::PrimaryID::RESERVED0:
+    case ColorSpace::PrimaryID::RESERVED:
+    case ColorSpace::PrimaryID::UNSPECIFIED:
+    case ColorSpace::PrimaryID::UNKNOWN:
+    case ColorSpace::PrimaryID::BT709:
+      // BT709 is our default case. Put it after the switch just
+      // in case we somehow get an id which is not listed in the switch.
+      // (We don't want to use "default", because we want the compiler
+      //  to tell us if we forgot some enum values.)
+      primaries.fRX = 0.640f;
+      primaries.fRY = 0.330f;
+      primaries.fGX = 0.300f;
+      primaries.fGY = 0.600f;
+      primaries.fBX = 0.150f;
+      primaries.fBY = 0.060f;
+      primaries.fWX = 0.3127f;
+      primaries.fWY = 0.3290f;
+      break;
+
+    case ColorSpace::PrimaryID::BT470M:
+      primaries.fRX = 0.67f;
+      primaries.fRY = 0.33f;
+      primaries.fGX = 0.21f;
+      primaries.fGY = 0.71f;
+      primaries.fBX = 0.14f;
+      primaries.fBY = 0.08f;
+      primaries.fWX = 0.31f;
+      primaries.fWY = 0.316f;
+      break;
+
+    case ColorSpace::PrimaryID::BT470BG:
+      primaries.fRX = 0.64f;
+      primaries.fRY = 0.33f;
+      primaries.fGX = 0.29f;
+      primaries.fGY = 0.60f;
+      primaries.fBX = 0.15f;
+      primaries.fBY = 0.06f;
+      primaries.fWX = 0.3127f;
+      primaries.fWY = 0.3290f;
+      break;
+
+    case ColorSpace::PrimaryID::SMPTE170M:
+    case ColorSpace::PrimaryID::SMPTE240M:
+      primaries.fRX = 0.630f;
+      primaries.fRY = 0.340f;
+      primaries.fGX = 0.310f;
+      primaries.fGY = 0.595f;
+      primaries.fBX = 0.155f;
+      primaries.fBY = 0.070f;
+      primaries.fWX = 0.3127f;
+      primaries.fWY = 0.3290f;
+      break;
+
+    case ColorSpace::PrimaryID::FILM:
+      primaries.fRX = 0.681f;
+      primaries.fRY = 0.319f;
+      primaries.fGX = 0.243f;
+      primaries.fGY = 0.692f;
+      primaries.fBX = 0.145f;
+      primaries.fBY = 0.049f;
+      primaries.fWX = 0.310f;
+      primaries.fWY = 0.136f;
+      break;
+
+    case ColorSpace::PrimaryID::BT2020:
+      primaries.fRX = 0.708f;
+      primaries.fRY = 0.292f;
+      primaries.fGX = 0.170f;
+      primaries.fGY = 0.797f;
+      primaries.fBX = 0.131f;
+      primaries.fBY = 0.046f;
+      primaries.fWX = 0.3127f;
+      primaries.fWY = 0.3290f;
+      break;
+
+    case ColorSpace::PrimaryID::SMPTEST428_1:
+      primaries.fRX = 1.0f;
+      primaries.fRY = 0.0f;
+      primaries.fGX = 0.0f;
+      primaries.fGY = 1.0f;
+      primaries.fBX = 0.0f;
+      primaries.fBY = 0.0f;
+      primaries.fWX = 1.0f / 3.0f;
+      primaries.fWY = 1.0f / 3.0f;
+      break;
+
+    case ColorSpace::PrimaryID::SMPTEST431_2:
+      primaries.fRX = 0.680f;
+      primaries.fRY = 0.320f;
+      primaries.fGX = 0.265f;
+      primaries.fGY = 0.690f;
+      primaries.fBX = 0.150f;
+      primaries.fBY = 0.060f;
+      primaries.fWX = 0.314f;
+      primaries.fWY = 0.351f;
+      break;
+
+    case ColorSpace::PrimaryID::SMPTEST432_1:
+      primaries.fRX = 0.680f;
+      primaries.fRY = 0.320f;
+      primaries.fGX = 0.265f;
+      primaries.fGY = 0.690f;
+      primaries.fBX = 0.150f;
+      primaries.fBY = 0.060f;
+      primaries.fWX = 0.3127f;
+      primaries.fWY = 0.3290f;
+      break;
+
+    case ColorSpace::PrimaryID::XYZ_D50:
+      primaries.fRX = 1.0f;
+      primaries.fRY = 0.0f;
+      primaries.fGX = 0.0f;
+      primaries.fGY = 1.0f;
+      primaries.fBX = 0.0f;
+      primaries.fBY = 0.0f;
+      primaries.fWX = 0.34567f;
+      primaries.fWY = 0.35850f;
+      break;
+  }
+  primaries.toXYZD50(to_XYZD50);
+}
+
+bool ColorSpace::GetTransferFunction(SkColorSpaceTransferFn* fn) const {
+  // Default to F(x) = pow(x, 1)
+  fn->fA = 1;
+  fn->fB = 0;
+  fn->fC = 1;
+  fn->fD = 0;
+  fn->fE = 0;
+  fn->fF = 0;
+  fn->fG = 1;
+
+  switch (transfer_) {
+    case ColorSpace::TransferID::CUSTOM:
+      fn->fA = custom_transfer_params_[0];
+      fn->fB = custom_transfer_params_[1];
+      fn->fC = custom_transfer_params_[2];
+      fn->fD = custom_transfer_params_[3];
+      fn->fE = custom_transfer_params_[4];
+      fn->fF = custom_transfer_params_[5];
+      fn->fG = custom_transfer_params_[6];
+      return true;
+    case ColorSpace::TransferID::LINEAR:
+      return true;
+    case ColorSpace::TransferID::GAMMA22:
+      fn->fG = 2.2f;
+      return true;
+    case ColorSpace::TransferID::GAMMA24:
+      fn->fG = 2.4f;
+      return true;
+    case ColorSpace::TransferID::GAMMA28:
+      fn->fG = 2.8f;
+      return true;
+    case ColorSpace::TransferID::RESERVED0:
+    case ColorSpace::TransferID::RESERVED:
+    case ColorSpace::TransferID::UNSPECIFIED:
+    case ColorSpace::TransferID::UNKNOWN:
+    // All unknown values default to BT709
+    case ColorSpace::TransferID::BT709:
+    case ColorSpace::TransferID::SMPTE170M:
+    case ColorSpace::TransferID::BT2020_10:
+    case ColorSpace::TransferID::BT2020_12:
+      fn->fA = 0.909672431050f;
+      fn->fB = 0.090327568950f;
+      fn->fC = 0.222222222222f;
+      fn->fD = 0.081242862158f;
+      fn->fG = 2.222222222222f;
+      return true;
+    case ColorSpace::TransferID::SMPTE240M:
+      fn->fA = 0.899626676224f;
+      fn->fB = 0.100373323776f;
+      fn->fC = 0.250000000000f;
+      fn->fD = 0.091286342118f;
+      fn->fG = 2.222222222222f;
+      return true;
+    case ColorSpace::TransferID::IEC61966_2_1:
+      fn->fA = 0.947867345704f;
+      fn->fB = 0.052132654296f;
+      fn->fC = 0.077399380805f;
+      fn->fD = 0.040449937172f;
+      fn->fG = 2.400000000000f;
+      return true;
+    case ColorSpace::TransferID::SMPTEST428_1:
+      fn->fA = 0.225615407568f;
+      fn->fE = -1.091041666667f;
+      fn->fG = 2.600000000000f;
+      return true;
+    case ColorSpace::TransferID::IEC61966_2_4:
+      // This could potentially be represented the same as IEC61966_2_1, but
+      // it handles negative values differently.
+      break;
+    case ColorSpace::TransferID::ARIB_STD_B67:
+    case ColorSpace::TransferID::BT1361_ECG:
+    case ColorSpace::TransferID::LOG:
+    case ColorSpace::TransferID::LOG_SQRT:
+    case ColorSpace::TransferID::SMPTEST2084:
+    case ColorSpace::TransferID::SMPTEST2084_NON_HDR:
+      break;
+  }
+
+  return false;
+}
+
+bool ColorSpace::GetInverseTransferFunction(SkColorSpaceTransferFn* fn) const {
+  if (!GetTransferFunction(fn))
+    return false;
+  *fn = InvertTransferFn(*fn);
+  return true;
+}
+
 }  // namespace gfx
diff --git a/ui/gfx/color_space.h b/ui/gfx/color_space.h
index df90dab..d7b2bd97 100644
--- a/ui/gfx/color_space.h
+++ b/ui/gfx/color_space.h
@@ -150,6 +150,8 @@
   static MatrixID MatrixIDFromInt(int matrix_id);
 
   static ColorSpace CreateSRGB();
+  static ColorSpace CreateCustom(const SkMatrix44& to_XYZD50,
+                                 const SkColorSpaceTransferFn& fn);
   // scRGB is like RGB, but linear and values outside of 0-1 are allowed.
   // scRGB is normally used with fp16 textures.
   static ColorSpace CreateSCRGBLinear();
@@ -170,14 +172,23 @@
   const sk_sp<SkColorSpace>& ToSkColorSpace() const { return sk_color_space_; }
   static ColorSpace FromSkColorSpace(const sk_sp<SkColorSpace>& sk_color_space);
 
+  void GetPrimaryMatrix(SkMatrix44* to_XYZD50) const;
+  bool GetTransferFunction(SkColorSpaceTransferFn* fn) const;
+  bool GetInverseTransferFunction(SkColorSpaceTransferFn* fn) const;
+
  private:
   PrimaryID primaries_ = PrimaryID::UNSPECIFIED;
   TransferID transfer_ = TransferID::UNSPECIFIED;
   MatrixID matrix_ = MatrixID::UNSPECIFIED;
   RangeID range_ = RangeID::LIMITED;
 
-  // Only used if primaries_ == PrimaryID::CUSTOM
-  float custom_primary_matrix_[12];
+  // Only used if primaries_ is PrimaryID::CUSTOM.
+  float custom_primary_matrix_[9];
+
+  // Only used if transfer_ is TransferID::CUSTOM. This array consists of the A
+  // through G entries of the SkColorSpaceTransferFn structure in alphabetical
+  // order.
+  float custom_transfer_params_[7];
 
   // This is used to look up the ICCProfile from which this ColorSpace was
   // created, if possible.
diff --git a/ui/gfx/color_transform.cc b/ui/gfx/color_transform.cc
index 3a63643..4d36fe29 100644
--- a/ui/gfx/color_transform.cc
+++ b/ui/gfx/color_transform.cc
@@ -21,6 +21,14 @@
 
 namespace gfx {
 
+float EvalSkTransferFn(const SkColorSpaceTransferFn& fn, float x) {
+  if (x < 0)
+    return 0;
+  if (x < fn.fD)
+    return fn.fC * x + fn.fF;
+  return powf(fn.fA * x + fn.fB, fn.fG) + fn.fE;
+}
+
 Transform Invert(const Transform& t) {
   Transform ret = t;
   if (!t.GetInverse(&ret)) {
@@ -29,180 +37,12 @@
   return ret;
 }
 
-GFX_EXPORT Transform GetPrimaryMatrix(ColorSpace::PrimaryID id) {
-  SkColorSpacePrimaries primaries = {0};
-  switch (id) {
-    case ColorSpace::PrimaryID::CUSTOM:
-      NOTREACHED();
-
-    case ColorSpace::PrimaryID::RESERVED0:
-    case ColorSpace::PrimaryID::RESERVED:
-    case ColorSpace::PrimaryID::UNSPECIFIED:
-    case ColorSpace::PrimaryID::UNKNOWN:
-    case ColorSpace::PrimaryID::BT709:
-      // BT709 is our default case. Put it after the switch just
-      // in case we somehow get an id which is not listed in the switch.
-      // (We don't want to use "default", because we want the compiler
-      //  to tell us if we forgot some enum values.)
-      primaries.fRX = 0.640f;
-      primaries.fRY = 0.330f;
-      primaries.fGX = 0.300f;
-      primaries.fGY = 0.600f;
-      primaries.fBX = 0.150f;
-      primaries.fBY = 0.060f;
-      primaries.fWX = 0.3127f;
-      primaries.fWY = 0.3290f;
-      break;
-
-    case ColorSpace::PrimaryID::BT470M:
-      primaries.fRX = 0.67f;
-      primaries.fRY = 0.33f;
-      primaries.fGX = 0.21f;
-      primaries.fGY = 0.71f;
-      primaries.fBX = 0.14f;
-      primaries.fBY = 0.08f;
-      primaries.fWX = 0.31f;
-      primaries.fWY = 0.316f;
-      break;
-
-    case ColorSpace::PrimaryID::BT470BG:
-      primaries.fRX = 0.64f;
-      primaries.fRY = 0.33f;
-      primaries.fGX = 0.29f;
-      primaries.fGY = 0.60f;
-      primaries.fBX = 0.15f;
-      primaries.fBY = 0.06f;
-      primaries.fWX = 0.3127f;
-      primaries.fWY = 0.3290f;
-      break;
-
-    case ColorSpace::PrimaryID::SMPTE170M:
-    case ColorSpace::PrimaryID::SMPTE240M:
-      primaries.fRX = 0.630f;
-      primaries.fRY = 0.340f;
-      primaries.fGX = 0.310f;
-      primaries.fGY = 0.595f;
-      primaries.fBX = 0.155f;
-      primaries.fBY = 0.070f;
-      primaries.fWX = 0.3127f;
-      primaries.fWY = 0.3290f;
-      break;
-
-    case ColorSpace::PrimaryID::FILM:
-      primaries.fRX = 0.681f;
-      primaries.fRY = 0.319f;
-      primaries.fGX = 0.243f;
-      primaries.fGY = 0.692f;
-      primaries.fBX = 0.145f;
-      primaries.fBY = 0.049f;
-      primaries.fWX = 0.310f;
-      primaries.fWY = 0.136f;
-      break;
-
-    case ColorSpace::PrimaryID::BT2020:
-      primaries.fRX = 0.708f;
-      primaries.fRY = 0.292f;
-      primaries.fGX = 0.170f;
-      primaries.fGY = 0.797f;
-      primaries.fBX = 0.131f;
-      primaries.fBY = 0.046f;
-      primaries.fWX = 0.3127f;
-      primaries.fWY = 0.3290f;
-      break;
-
-    case ColorSpace::PrimaryID::SMPTEST428_1:
-      primaries.fRX = 1.0f;
-      primaries.fRY = 0.0f;
-      primaries.fGX = 0.0f;
-      primaries.fGY = 1.0f;
-      primaries.fBX = 0.0f;
-      primaries.fBY = 0.0f;
-      primaries.fWX = 1.0f / 3.0f;
-      primaries.fWY = 1.0f / 3.0f;
-      break;
-
-    case ColorSpace::PrimaryID::SMPTEST431_2:
-      primaries.fRX = 0.680f;
-      primaries.fRY = 0.320f;
-      primaries.fGX = 0.265f;
-      primaries.fGY = 0.690f;
-      primaries.fBX = 0.150f;
-      primaries.fBY = 0.060f;
-      primaries.fWX = 0.314f;
-      primaries.fWY = 0.351f;
-      break;
-
-    case ColorSpace::PrimaryID::SMPTEST432_1:
-      primaries.fRX = 0.680f;
-      primaries.fRY = 0.320f;
-      primaries.fGX = 0.265f;
-      primaries.fGY = 0.690f;
-      primaries.fBX = 0.150f;
-      primaries.fBY = 0.060f;
-      primaries.fWX = 0.3127f;
-      primaries.fWY = 0.3290f;
-      break;
-
-    case ColorSpace::PrimaryID::XYZ_D50:
-      primaries.fRX = 1.0f;
-      primaries.fRY = 0.0f;
-      primaries.fGX = 0.0f;
-      primaries.fGY = 1.0f;
-      primaries.fBX = 0.0f;
-      primaries.fBY = 0.0f;
-      primaries.fWX = 0.34567f;
-      primaries.fWY = 0.35850f;
-      break;
-  }
-
-  SkMatrix44 matrix;
-  primaries.toXYZD50(&matrix);
-  return Transform(matrix);
-}
-
-GFX_EXPORT float FromLinear(ColorSpace::TransferID id, float v) {
+float FromLinear(ColorSpace::TransferID id, float v) {
   switch (id) {
     case ColorSpace::TransferID::SMPTEST2084_NON_HDR:
       // Should already be handled.
-      NOTREACHED();
-    case ColorSpace::TransferID::CUSTOM:
-    // TODO(hubbe): Actually implement custom transfer functions.
-    case ColorSpace::TransferID::RESERVED0:
-    case ColorSpace::TransferID::RESERVED:
-    case ColorSpace::TransferID::UNSPECIFIED:
-    case ColorSpace::TransferID::UNKNOWN:
-    // All unknown values default to BT709
-
-    case ColorSpace::TransferID::BT709:
-    case ColorSpace::TransferID::SMPTE170M:
-    case ColorSpace::TransferID::BT2020_10:
-    case ColorSpace::TransferID::BT2020_12:
-      // BT709 is our "default" cause, so put the code after the switch
-      // to avoid "control reaches end of non-void function" errors.
       break;
 
-    case ColorSpace::TransferID::GAMMA22:
-      v = fmax(0.0f, v);
-      return powf(v, 1.0f / 2.2f);
-
-    case ColorSpace::TransferID::GAMMA28:
-      v = fmax(0.0f, v);
-      return powf(v, 1.0f / 2.8f);
-
-    case ColorSpace::TransferID::SMPTE240M: {
-      v = fmax(0.0f, v);
-      float a = 1.11157219592173128753f;
-      float b = 0.02282158552944503135f;
-      if (v <= b) {
-        return 4.0f * v;
-      } else {
-        return a * powf(v, 0.45f) - (a - 1.0f);
-      }
-    }
-
-    case ColorSpace::TransferID::LINEAR:
-      return v;
-
     case ColorSpace::TransferID::LOG:
       if (v < 0.01f)
         return 0.0f;
@@ -238,16 +78,6 @@
       }
     }
 
-    case ColorSpace::TransferID::IEC61966_2_1: {  // SRGB
-      v = fmax(0.0f, v);
-      float a = 1.055f;
-      float b = 0.0031308f;
-      if (v < b) {
-        return 12.92f * v;
-      } else {
-        return a * powf(v, 1.0f / 2.4f) - (a - 1.0f);
-      }
-    }
     case ColorSpace::TransferID::SMPTEST2084: {
       // Go from scRGB levels to 0-1.
       v *= 80.0f / 10000.0f;
@@ -260,10 +90,6 @@
       return powf((c1 + c2 * powf(v, m1)) / (1.0f + c3 * powf(v, m1)), m2);
     }
 
-    case ColorSpace::TransferID::SMPTEST428_1:
-      v = fmax(0.0f, v);
-      return powf(48.0f * v + 52.37f, 1.0f / 2.6f);
-
     // Spec: http://www.arib.or.jp/english/html/overview/doc/2-STD-B67v1_0.pdf
     case ColorSpace::TransferID::ARIB_STD_B67: {
       const float a = 0.17883277f;
@@ -276,62 +102,16 @@
         return a * log(v - b) + c;
     }
 
-    // Chrome-specific values below
-    case ColorSpace::TransferID::GAMMA24:
-      v = fmax(0.0f, v);
-      return powf(v, 1.0f / 2.4f);
+    default:
+      // Handled by SkColorSpaceTransferFn.
+      break;
   }
-
-  v = fmax(0.0f, v);
-  float a = 1.099296826809442f;
-  float b = 0.018053968510807f;
-  if (v <= b) {
-    return 4.5f * v;
-  } else {
-    return a * powf(v, 0.45f) - (a - 1.0f);
-  }
+  NOTREACHED();
+  return 0;
 }
 
-GFX_EXPORT float ToLinear(ColorSpace::TransferID id, float v) {
+float ToLinear(ColorSpace::TransferID id, float v) {
   switch (id) {
-    case ColorSpace::TransferID::CUSTOM:
-    // TODO(hubbe): Actually implement custom transfer functions.
-    case ColorSpace::TransferID::RESERVED0:
-    case ColorSpace::TransferID::RESERVED:
-    case ColorSpace::TransferID::UNSPECIFIED:
-    case ColorSpace::TransferID::UNKNOWN:
-    // All unknown values default to BT709
-
-    case ColorSpace::TransferID::BT709:
-    case ColorSpace::TransferID::SMPTE170M:
-    case ColorSpace::TransferID::BT2020_10:
-    case ColorSpace::TransferID::BT2020_12:
-      // BT709 is our "default" cause, so put the code after the switch
-      // to avoid "control reaches end of non-void function" errors.
-      break;
-
-    case ColorSpace::TransferID::GAMMA22:
-      v = fmax(0.0f, v);
-      return powf(v, 2.2f);
-
-    case ColorSpace::TransferID::GAMMA28:
-      v = fmax(0.0f, v);
-      return powf(v, 2.8f);
-
-    case ColorSpace::TransferID::SMPTE240M: {
-      v = fmax(0.0f, v);
-      float a = 1.11157219592173128753f;
-      float b = 0.02282158552944503135f;
-      if (v <= FromLinear(ColorSpace::TransferID::SMPTE240M, b)) {
-        return v / 4.0f;
-      } else {
-        return powf((v + a - 1.0f) / a, 1.0f / 0.45f);
-      }
-    }
-
-    case ColorSpace::TransferID::LINEAR:
-      return v;
-
     case ColorSpace::TransferID::LOG:
       if (v < 0.0f)
         return 0.0f;
@@ -367,17 +147,6 @@
       }
     }
 
-    case ColorSpace::TransferID::IEC61966_2_1: {  // SRGB
-      v = fmax(0.0f, v);
-      float a = 1.055f;
-      float b = 0.0031308f;
-      if (v < FromLinear(ColorSpace::TransferID::IEC61966_2_1, b)) {
-        return v / 12.92f;
-      } else {
-        return powf((v + a - 1.0f) / a, 2.4f);
-      }
-    }
-
     case ColorSpace::TransferID::SMPTEST2084: {
       v = fmax(0.0f, v);
       float m1 = (2610.0f / 4096.0f) / 4.0f;
@@ -395,14 +164,6 @@
       return v;
     }
 
-    case ColorSpace::TransferID::SMPTEST428_1:
-      return (powf(v, 2.6f) - 52.37f) / 48.0f;
-
-    // Chrome-specific values below
-    case ColorSpace::TransferID::GAMMA24:
-      v = fmax(0.0f, v);
-      return powf(v, 2.4f);
-
     case ColorSpace::TransferID::SMPTEST2084_NON_HDR:
       v = fmax(0.0f, v);
       return fmin(2.3f * pow(v, 2.8f), v / 5.0f + 0.8f);
@@ -421,16 +182,13 @@
       }
       return v_;
     }
-  }
 
-  v = fmax(0.0f, v);
-  float a = 1.099296826809442f;
-  float b = 0.018053968510807f;
-  if (v < FromLinear(ColorSpace::TransferID::BT709, b)) {
-    return v / 4.5f;
-  } else {
-    return powf((v + a - 1.0f) / a, 1.0f / 0.45f);
+    default:
+      // Handled by SkColorSpaceTransferFn.
+      break;
   }
+  NOTREACHED();
+  return 0;
 }
 
 GFX_EXPORT Transform GetTransferMatrix(ColorSpace::MatrixID id) {
@@ -617,8 +375,10 @@
 
 class ColorTransformFromLinear : public ColorTransformInternal {
  public:
-  explicit ColorTransformFromLinear(ColorSpace::TransferID transfer)
-      : transfer_(transfer) {}
+  explicit ColorTransformFromLinear(ColorSpace::TransferID transfer,
+                                    const SkColorSpaceTransferFn& fn,
+                                    bool fn_valid)
+      : transfer_(transfer), fn_(fn), fn_valid_(fn_valid) {}
   bool Prepend(ColorTransformInternal* prev) override {
     return prev->Join(*this);
   }
@@ -626,22 +386,34 @@
   bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; }
 
   void transform(ColorTransform::TriStim* colors, size_t num) override {
-    for (size_t i = 0; i < num; i++) {
-      colors[i].set_x(FromLinear(transfer_, colors[i].x()));
-      colors[i].set_y(FromLinear(transfer_, colors[i].y()));
-      colors[i].set_z(FromLinear(transfer_, colors[i].z()));
+    if (fn_valid_) {
+      for (size_t i = 0; i < num; i++) {
+        colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x()));
+        colors[i].set_y(EvalSkTransferFn(fn_, colors[i].y()));
+        colors[i].set_z(EvalSkTransferFn(fn_, colors[i].z()));
+      }
+    } else {
+      for (size_t i = 0; i < num; i++) {
+        colors[i].set_x(FromLinear(transfer_, colors[i].x()));
+        colors[i].set_y(FromLinear(transfer_, colors[i].y()));
+        colors[i].set_z(FromLinear(transfer_, colors[i].z()));
+      }
     }
   }
 
  private:
   friend class ColorTransformToLinear;
   ColorSpace::TransferID transfer_;
+  SkColorSpaceTransferFn fn_;
+  bool fn_valid_ = false;
 };
 
 class ColorTransformToLinear : public ColorTransformInternal {
  public:
-  explicit ColorTransformToLinear(ColorSpace::TransferID transfer)
-      : transfer_(transfer) {}
+  explicit ColorTransformToLinear(ColorSpace::TransferID transfer,
+                                  const SkColorSpaceTransferFn& fn,
+                                  bool fn_valid)
+      : transfer_(transfer), fn_(fn), fn_valid_(fn_valid) {}
 
   bool Prepend(ColorTransformInternal* prev) override {
     return prev->Join(*this);
@@ -677,7 +449,13 @@
   }
 
   void transform(ColorTransform::TriStim* colors, size_t num) override {
-    if (transfer_ == ColorSpace::TransferID::SMPTEST2084_NON_HDR) {
+    if (fn_valid_) {
+      for (size_t i = 0; i < num; i++) {
+        colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x()));
+        colors[i].set_y(EvalSkTransferFn(fn_, colors[i].y()));
+        colors[i].set_z(EvalSkTransferFn(fn_, colors[i].z()));
+      }
+    } else if (transfer_ == ColorSpace::TransferID::SMPTEST2084_NON_HDR) {
       for (size_t i = 0; i < num; i++) {
         ColorTransform::TriStim ret(ToLinear(transfer_, colors[i].x()),
                                     ToLinear(transfer_, colors[i].y()),
@@ -703,6 +481,8 @@
 
  private:
   ColorSpace::TransferID transfer_;
+  SkColorSpaceTransferFn fn_;
+  bool fn_valid_ = false;
 };
 
 // BT2020 Constant Luminance is different than most other
@@ -858,17 +638,9 @@
 class ColorSpaceToColorSpaceTransform {
  public:
   static Transform GetPrimaryTransform(const ColorSpace& c) {
-    if (c.primaries_ == ColorSpace::PrimaryID::CUSTOM) {
-      return Transform(c.custom_primary_matrix_[0], c.custom_primary_matrix_[1],
-                       c.custom_primary_matrix_[2], c.custom_primary_matrix_[3],
-                       c.custom_primary_matrix_[4], c.custom_primary_matrix_[5],
-                       c.custom_primary_matrix_[6], c.custom_primary_matrix_[7],
-                       c.custom_primary_matrix_[8], c.custom_primary_matrix_[9],
-                       c.custom_primary_matrix_[10],
-                       c.custom_primary_matrix_[11], 0.0f, 0.0f, 0.0f, 1.0f);
-    } else {
-      return GetPrimaryMatrix(c.primaries_);
-    }
+    SkMatrix44 sk_matrix;
+    c.GetPrimaryMatrix(&sk_matrix);
+    return Transform(sk_matrix);
   }
 
   static void ColorSpaceToColorSpace(ColorSpace from,
@@ -911,11 +683,18 @@
 
       // TODO(hubbe): shrink gamuts here (never stretch gamuts)
     }
+
     builder->Append(base::MakeUnique<ColorTransformMatrix>(
         GetRangeAdjustMatrix(from.range_, from.matrix_)));
+
     builder->Append(base::MakeUnique<ColorTransformMatrix>(
         Invert(GetTransferMatrix(from.matrix_))));
-    builder->Append(base::MakeUnique<ColorTransformToLinear>(from.transfer_));
+
+    SkColorSpaceTransferFn to_linear_fn;
+    bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn);
+    builder->Append(base::MakeUnique<ColorTransformToLinear>(
+        from.transfer_, to_linear_fn, to_linear_fn_valid));
+
     if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) {
       // BT2020 CL is a special case.
       builder->Append(base::MakeUnique<ColorTransformFromBT2020CL>());
@@ -930,9 +709,14 @@
       builder->Append(base::MakeUnique<ColorTransformToBT2020CL>());
     }
 
-    builder->Append(base::MakeUnique<ColorTransformFromLinear>(to.transfer_));
+    SkColorSpaceTransferFn from_linear_fn;
+    bool from_linear_fn_valid = to.GetInverseTransferFunction(&from_linear_fn);
+    builder->Append(base::MakeUnique<ColorTransformFromLinear>(
+        to.transfer_, from_linear_fn, from_linear_fn_valid));
+
     builder->Append(
         base::MakeUnique<ColorTransformMatrix>(GetTransferMatrix(to.matrix_)));
+
     builder->Append(base::MakeUnique<ColorTransformMatrix>(
         Invert(GetRangeAdjustMatrix(to.range_, to.matrix_))));
   }
@@ -1028,4 +812,33 @@
   return builder.GetTransform();
 }
 
+// static
+float ColorTransform::ToLinearForTesting(ColorSpace::TransferID transfer,
+                                         float v) {
+  ColorSpace space(ColorSpace::PrimaryID::BT709, transfer,
+                   ColorSpace::MatrixID::RGB, ColorSpace::RangeID::FULL);
+  SkColorSpaceTransferFn to_linear_fn;
+  bool to_linear_fn_valid = space.GetTransferFunction(&to_linear_fn);
+  ColorTransformToLinear to_linear_transform(transfer, to_linear_fn,
+                                             to_linear_fn_valid);
+  TriStim color(v, v, v);
+  to_linear_transform.transform(&color, 1);
+  return color.x();
+}
+
+// static
+float ColorTransform::FromLinearForTesting(ColorSpace::TransferID transfer,
+                                           float v) {
+  ColorSpace space(ColorSpace::PrimaryID::BT709, transfer,
+                   ColorSpace::MatrixID::RGB, ColorSpace::RangeID::FULL);
+  SkColorSpaceTransferFn from_linear_fn;
+  bool from_linear_fn_valid = space.GetInverseTransferFunction(&from_linear_fn);
+
+  ColorTransformFromLinear from_linear_transform(transfer, from_linear_fn,
+                                                 from_linear_fn_valid);
+  TriStim color(v, v, v);
+  from_linear_transform.transform(&color, 1);
+  return color.x();
+}
+
 }  // namespace gfx
diff --git a/ui/gfx/color_transform.h b/ui/gfx/color_transform.h
index 092608c..1d99617 100644
--- a/ui/gfx/color_transform.h
+++ b/ui/gfx/color_transform.h
@@ -9,13 +9,12 @@
 #include <stdint.h>
 
 #include "build/build_config.h"
+#include "ui/gfx/color_space.h"
 #include "ui/gfx/geometry/point3_f.h"
 #include "ui/gfx/gfx_export.h"
 
 namespace gfx {
 
-class ColorSpace;
-
 class GFX_EXPORT ColorTransform {
  public:
   enum class Intent { INTENT_ABSOLUTE, INTENT_PERCEPTUAL, TEST_NO_OPT };
@@ -33,6 +32,9 @@
       const ColorSpace& from,
       const ColorSpace& to,
       Intent intent);
+
+  static float ToLinearForTesting(ColorSpace::TransferID id, float v);
+  static float FromLinearForTesting(ColorSpace::TransferID id, float v);
 };
 }  // namespace gfx
 
diff --git a/ui/gfx/color_transform_unittest.cc b/ui/gfx/color_transform_unittest.cc
index c992687..63ba82a8 100644
--- a/ui/gfx/color_transform_unittest.cc
+++ b/ui/gfx/color_transform_unittest.cc
@@ -13,10 +13,7 @@
 namespace gfx {
 
 // Internal functions, exposted for testing.
-GFX_EXPORT Transform GetPrimaryMatrix(ColorSpace::PrimaryID id);
 GFX_EXPORT Transform GetTransferMatrix(ColorSpace::MatrixID id);
-GFX_EXPORT float ToLinear(ColorSpace::TransferID id, float v);
-GFX_EXPORT float FromLinear(ColorSpace::TransferID id, float v);
 
 ColorSpace::PrimaryID all_primaries[] = {
     ColorSpace::PrimaryID::BT709,        ColorSpace::PrimaryID::BT470M,
@@ -117,6 +114,7 @@
   ICCProfile srgb_icc = ICCProfileForTestingSRGB();
   ColorSpace sRGB = srgb_icc.GetColorSpace();
   ColorSpace sRGB2 = sRGB;
+  const float kEpsilon = 1.5f / 255.f;
 
   // Prevent sRGB2 from using a cached ICC profile.
   sRGB2.icc_profile_id_ = 0;
@@ -126,27 +124,27 @@
 
   ColorTransform::TriStim tmp(1.0f, 1.0f, 1.0f);
   t->transform(&tmp, 1);
-  EXPECT_NEAR(tmp.x(), 1.0f, 0.001f);
-  EXPECT_NEAR(tmp.y(), 1.0f, 0.001f);
-  EXPECT_NEAR(tmp.z(), 1.0f, 0.001f);
+  EXPECT_NEAR(tmp.x(), 1.0f, kEpsilon);
+  EXPECT_NEAR(tmp.y(), 1.0f, kEpsilon);
+  EXPECT_NEAR(tmp.z(), 1.0f, kEpsilon);
 
   tmp = ColorTransform::TriStim(1.0f, 0.0f, 0.0f);
   t->transform(&tmp, 1);
-  EXPECT_NEAR(tmp.x(), 1.0f, 0.001f);
-  EXPECT_NEAR(tmp.y(), 0.0f, 0.001f);
-  EXPECT_NEAR(tmp.z(), 0.0f, 0.001f);
+  EXPECT_NEAR(tmp.x(), 1.0f, kEpsilon);
+  EXPECT_NEAR(tmp.y(), 0.0f, kEpsilon);
+  EXPECT_NEAR(tmp.z(), 0.0f, kEpsilon);
 
   tmp = ColorTransform::TriStim(0.0f, 1.0f, 0.0f);
   t->transform(&tmp, 1);
-  EXPECT_NEAR(tmp.x(), 0.0f, 0.001f);
-  EXPECT_NEAR(tmp.y(), 1.0f, 0.001f);
-  EXPECT_NEAR(tmp.z(), 0.0f, 0.001f);
+  EXPECT_NEAR(tmp.x(), 0.0f, kEpsilon);
+  EXPECT_NEAR(tmp.y(), 1.0f, kEpsilon);
+  EXPECT_NEAR(tmp.z(), 0.0f, kEpsilon);
 
   tmp = ColorTransform::TriStim(0.0f, 0.0f, 1.0f);
   t->transform(&tmp, 1);
-  EXPECT_NEAR(tmp.x(), 0.0f, 0.001f);
-  EXPECT_NEAR(tmp.y(), 0.0f, 0.001f);
-  EXPECT_NEAR(tmp.z(), 1.0f, 0.001f);
+  EXPECT_NEAR(tmp.x(), 0.0f, kEpsilon);
+  EXPECT_NEAR(tmp.y(), 0.0f, kEpsilon);
+  EXPECT_NEAR(tmp.z(), 1.0f, kEpsilon);
 }
 
 TEST(SimpleColorSpace, UnknownToSRGB) {
@@ -174,18 +172,6 @@
   EXPECT_GT(tmp.z(), tmp.y());
 }
 
-class PrimaryTest : public testing::TestWithParam<ColorSpace::PrimaryID> {};
-
-TEST_P(PrimaryTest, checkInvertible) {
-  EXPECT_EQ(GetPrimaryMatrix(GetParam()).matrix().get(3, 3), 1.0f);
-  // Check that all primary matrices are invertable.
-  EXPECT_TRUE(GetPrimaryMatrix(GetParam()).IsInvertible());
-}
-
-INSTANTIATE_TEST_CASE_P(ColorSpace,
-                        PrimaryTest,
-                        testing::ValuesIn(all_primaries));
-
 class MatrixTest : public testing::TestWithParam<ColorSpace::MatrixID> {};
 
 TEST_P(MatrixTest, checkInvertible) {
@@ -202,8 +188,8 @@
 
 TEST_P(TransferTest, basicTest) {
   for (float x = 0.0f; x <= 1.0f; x += 1.0f / 128.0f) {
-    float linear = ToLinear(GetParam(), x);
-    float x2 = FromLinear(GetParam(), linear);
+    float linear = ColorTransform::ToLinearForTesting(GetParam(), x);
+    float x2 = ColorTransform::FromLinearForTesting(GetParam(), linear);
     EXPECT_NEAR(x, x2, 0.001f);
   }
 }
diff --git a/ui/gfx/icc_profile.cc b/ui/gfx/icc_profile.cc
index c5e84d1..645b569 100644
--- a/ui/gfx/icc_profile.cc
+++ b/ui/gfx/icc_profile.cc
@@ -9,6 +9,8 @@
 #include "base/containers/mru_cache.h"
 #include "base/lazy_instance.h"
 #include "base/synchronization/lock.h"
+#include "third_party/skia/include/core/SkData.h"
+#include "third_party/skia/include/core/SkICC.h"
 #include "ui/gfx/color_transform.h"
 
 namespace gfx {
@@ -43,17 +45,7 @@
 ICCProfile::~ICCProfile() = default;
 
 bool ICCProfile::operator==(const ICCProfile& other) const {
-  if (type_ != other.type_)
-    return false;
-  switch (type_) {
-    case Type::INVALID:
-      return true;
-    case Type::FROM_COLOR_SPACE:
-      return color_space_ == other.color_space_;
-    case Type::FROM_DATA:
-      return data_ == other.data_;
-  }
-  return false;
+  return data_ == data_;
 }
 
 bool ICCProfile::operator!=(const ICCProfile& other) const {
@@ -61,37 +53,37 @@
 }
 
 // static
-ICCProfile ICCProfile::FromData(const char* data, size_t size) {
-  ICCProfile icc_profile;
-  if (IsValidProfileLength(size)) {
-    icc_profile.type_ = Type::FROM_DATA;
-    icc_profile.data_.insert(icc_profile.data_.begin(), data, data + size);
-  } else {
+ICCProfile ICCProfile::FromData(const void* data, size_t size) {
+  if (!IsValidProfileLength(size)) {
+    if (size != 0)
+      DLOG(ERROR) << "Invalid ICC profile length: " << size << ".";
     return ICCProfile();
   }
 
-  Cache& cache = g_cache.Get();
-  base::AutoLock lock(cache.lock);
-
-  // Linearly search the cached ICC profiles to find one with the same data.
-  // If it exists, re-use its id and touch it in the cache.
-  for (auto iter = cache.id_to_icc_profile_mru.begin();
-       iter != cache.id_to_icc_profile_mru.end(); ++iter) {
-    if (icc_profile.data_ == iter->second.data_) {
-      icc_profile = iter->second;
-      cache.id_to_icc_profile_mru.Get(icc_profile.id_);
-      return icc_profile;
+  uint64_t new_profile_id = 0;
+  const char* data_as_char = reinterpret_cast<const char*>(data);
+  {
+    // Linearly search the cached ICC profiles to find one with the same data.
+    // If it exists, re-use its id and touch it in the cache.
+    Cache& cache = g_cache.Get();
+    base::AutoLock lock(cache.lock);
+    for (auto iter = cache.id_to_icc_profile_mru.begin();
+         iter != cache.id_to_icc_profile_mru.end(); ++iter) {
+      const std::vector<char>& iter_data = iter->second.data_;
+      if (iter_data.size() != size || memcmp(data, iter_data.data(), size))
+        continue;
+      auto found = cache.id_to_icc_profile_mru.Get(iter->second.id_);
+      return found->second;
     }
+    new_profile_id = cache.next_unused_id++;
   }
 
   // Create a new cached id and add it to the cache.
-  icc_profile.id_ = cache.next_unused_id++;
-  icc_profile.color_space_ =
-      ColorSpace(ColorSpace::PrimaryID::CUSTOM, ColorSpace::TransferID::CUSTOM,
-                 ColorSpace::MatrixID::RGB, ColorSpace::RangeID::FULL);
-  icc_profile.color_space_.icc_profile_id_ = icc_profile.id_;
-  icc_profile.color_space_.sk_color_space_ = SkColorSpace::MakeICC(data, size);
-  cache.id_to_icc_profile_mru.Put(icc_profile.id_, icc_profile);
+  ICCProfile icc_profile;
+  icc_profile.id_ = new_profile_id;
+  icc_profile.data_.insert(icc_profile.data_.begin(), data_as_char,
+                           data_as_char + size);
+  icc_profile.ComputeColorSpaceAndCache();
   return icc_profile;
 }
 
@@ -112,19 +104,32 @@
   if (color_space.icc_profile_id_) {
     Cache& cache = g_cache.Get();
     base::AutoLock lock(cache.lock);
-
     auto found = cache.id_to_icc_profile_mru.Get(color_space.icc_profile_id_);
-    if (found != cache.id_to_icc_profile_mru.end()) {
+    if (found != cache.id_to_icc_profile_mru.end())
       return found->second;
-    }
   }
 
-  // TODO(ccameron): Support constructing ICC profiles from arbitrary ColorSpace
-  // objects.
-  ICCProfile icc_profile;
-  icc_profile.type_ = gfx::ICCProfile::Type::FROM_COLOR_SPACE;
-  icc_profile.color_space_ = color_space;
-  return icc_profile;
+  // Otherwise, construct an ICC profile based on the best approximated
+  // primaries and matrix.
+  SkMatrix44 to_XYZD50_matrix;
+  color_space.GetPrimaryMatrix(&to_XYZD50_matrix);
+  SkColorSpaceTransferFn fn;
+  if (!color_space.GetTransferFunction(&fn)) {
+    DLOG(ERROR) << "Failed to get ColorSpace transfer function for ICCProfile.";
+    return ICCProfile();
+  }
+
+  sk_sp<SkData> data = SkICC::WriteToICC(fn, to_XYZD50_matrix);
+  if (!data) {
+    DLOG(ERROR) << "Failed to create SkICC.";
+    return ICCProfile();
+  }
+
+  // gfx::ColorTransform assumes that this will return an empty profile for any
+  // color space that was not constructed from an ICC profile.
+  // TODO(ccameron): Fix this assumption.
+  // return FromData(data->data(), data->size());
+  return ICCProfile();
 }
 
 ICCProfile ICCProfile::FromSkColorSpace(sk_sp<SkColorSpace> color_space) {
@@ -148,6 +153,7 @@
 
   // TODO(ccameron): Support constructing ICC profiles from arbitrary
   // SkColorSpace objects.
+  DLOG(ERROR) << "Failed to find ICC profile matching SkColorSpace.";
   return icc_profile;
 }
 
@@ -155,68 +161,85 @@
   return data_;
 }
 
-ColorSpace ICCProfile::GetColorSpace() const {
-  if (type_ == Type::INVALID)
-    return gfx::ColorSpace();
-  if (type_ == Type::FROM_COLOR_SPACE)
-    return color_space_;
+const ColorSpace& ICCProfile::GetColorSpace() const {
+  // Move this ICC profile to the most recently used end of the cache,
+  // inserting if needed.
+  if (id_) {
+    Cache& cache = g_cache.Get();
+    base::AutoLock lock(cache.lock);
+    auto found = cache.id_to_icc_profile_mru.Get(id_);
+    if (found == cache.id_to_icc_profile_mru.end())
+      found = cache.id_to_icc_profile_mru.Put(id_, *this);
+  }
+  return color_space_;
+}
 
-  ColorSpace color_space = color_space_;
+void ICCProfile::ComputeColorSpaceAndCache() {
+  if (!id_)
+    return;
 
-  // Move this ICC profile to the most recently used end of the cache.
+  // If this already exists in the cache, just update its |color_space_|.
   {
     Cache& cache = g_cache.Get();
     base::AutoLock lock(cache.lock);
-
     auto found = cache.id_to_icc_profile_mru.Get(id_);
-    if (found == cache.id_to_icc_profile_mru.end())
-      cache.id_to_icc_profile_mru.Put(id_, *this);
+    if (found != cache.id_to_icc_profile_mru.end()) {
+      color_space_ = found->second.color_space_;
+      return;
+    }
   }
 
-  ColorSpace unity_colorspace(
-      ColorSpace::PrimaryID::CUSTOM, ColorSpace::TransferID::LINEAR,
+  // Compute the color space.
+  color_space_ = gfx::ColorSpace(
+      ColorSpace::PrimaryID::CUSTOM, ColorSpace::TransferID::CUSTOM,
       ColorSpace::MatrixID::RGB, ColorSpace::RangeID::FULL);
-  unity_colorspace.custom_primary_matrix_[0] = 1.0f;
-  unity_colorspace.custom_primary_matrix_[1] = 0.0f;
-  unity_colorspace.custom_primary_matrix_[2] = 0.0f;
-  unity_colorspace.custom_primary_matrix_[3] = 0.0f;
+  color_space_.icc_profile_id_ = id_;
+  color_space_.sk_color_space_ =
+      SkColorSpace::MakeICC(data_.data(), data_.size());
 
-  unity_colorspace.custom_primary_matrix_[4] = 0.0f;
-  unity_colorspace.custom_primary_matrix_[5] = 1.0f;
-  unity_colorspace.custom_primary_matrix_[6] = 0.0f;
-  unity_colorspace.custom_primary_matrix_[7] = 0.0f;
+  sk_sp<SkICC> sk_icc = SkICC::Make(data_.data(), data_.size());
+  if (sk_icc) {
+    bool result;
+    SkMatrix44 to_XYZD50_matrix;
+    result = sk_icc->toXYZD50(&to_XYZD50_matrix);
+    if (result) {
+      for (int row = 0; row < 3; ++row) {
+        for (int col = 0; col < 3; ++col) {
+          color_space_.custom_primary_matrix_[3 * row + col] =
+              to_XYZD50_matrix.get(row, col);
+        }
+      }
+    } else {
+      // Just say that the primaries were the sRGB primaries if we can't
+      // extract them.
+      color_space_.primaries_ = ColorSpace::PrimaryID::BT709;
+      DLOG(ERROR) << "Unable to handle ICCProfile primaries.";
+    }
+    SkColorSpaceTransferFn fn;
+    result = sk_icc->isNumericalTransferFn(&fn);
+    if (result) {
+      color_space_.custom_transfer_params_[0] = fn.fA;
+      color_space_.custom_transfer_params_[1] = fn.fB;
+      color_space_.custom_transfer_params_[2] = fn.fC;
+      color_space_.custom_transfer_params_[3] = fn.fD;
+      color_space_.custom_transfer_params_[4] = fn.fE;
+      color_space_.custom_transfer_params_[5] = fn.fF;
+      color_space_.custom_transfer_params_[6] = fn.fG;
+    } else {
+      // Just say that the transfer function was sRGB if we cannot read it.
+      // TODO(ccameron): Use a least squares approximation of the transfer
+      // function when it is not numerical.
+      color_space_.transfer_ = ColorSpace::TransferID::IEC61966_2_1;
+      DLOG(ERROR) << "Unable to handle ICCProfile transfer function.";
+    }
+  }
 
-  unity_colorspace.custom_primary_matrix_[8] = 0.0f;
-  unity_colorspace.custom_primary_matrix_[9] = 0.0f;
-  unity_colorspace.custom_primary_matrix_[10] = 1.0f;
-  unity_colorspace.custom_primary_matrix_[11] = 0.0f;
-
-  // This will look up and use the ICC profile.
-  std::unique_ptr<ColorTransform> transform(ColorTransform::NewColorTransform(
-      color_space, unity_colorspace, ColorTransform::Intent::INTENT_ABSOLUTE));
-
-  ColorTransform::TriStim tmp[4];
-  tmp[0].set_x(1.0f);
-  tmp[1].set_y(1.0f);
-  tmp[2].set_z(1.0f);
-  transform->transform(tmp, arraysize(tmp));
-
-  color_space.custom_primary_matrix_[0] = tmp[0].x() - tmp[3].x();
-  color_space.custom_primary_matrix_[1] = tmp[1].x() - tmp[3].x();
-  color_space.custom_primary_matrix_[2] = tmp[2].x() - tmp[3].x();
-  color_space.custom_primary_matrix_[3] = tmp[3].x();
-
-  color_space.custom_primary_matrix_[4] = tmp[0].y() - tmp[3].y();
-  color_space.custom_primary_matrix_[5] = tmp[1].y() - tmp[3].y();
-  color_space.custom_primary_matrix_[6] = tmp[2].y() - tmp[3].y();
-  color_space.custom_primary_matrix_[7] = tmp[3].y();
-
-  color_space.custom_primary_matrix_[8] = tmp[0].z() - tmp[3].z();
-  color_space.custom_primary_matrix_[9] = tmp[1].z() - tmp[3].z();
-  color_space.custom_primary_matrix_[10] = tmp[2].z() - tmp[3].z();
-  color_space.custom_primary_matrix_[11] = tmp[3].z();
-
-  return color_space;
+  // Add to the cache.
+  {
+    Cache& cache = g_cache.Get();
+    base::AutoLock lock(cache.lock);
+    cache.id_to_icc_profile_mru.Put(id_, *this);
+  }
 }
 
 // static
diff --git a/ui/gfx/icc_profile.h b/ui/gfx/icc_profile.h
index e719c16..c6170c61 100644
--- a/ui/gfx/icc_profile.h
+++ b/ui/gfx/icc_profile.h
@@ -23,10 +23,6 @@
 
 namespace gfx {
 
-namespace mojom {
-class ICCProfileDataView;
-}
-
 // Used to represent a full ICC profile, usually retrieved from a monitor. It
 // can be lossily compressed into a ColorSpace object. This structure should
 // only be sent from higher-privilege processes to lower-privilege processes,
@@ -54,14 +50,13 @@
   // Internally, this will make an effort to create an identical ICCProfile
   // to the one that created |color_space|, but this is not guaranteed.
   static ICCProfile FromColorSpace(const gfx::ColorSpace& color_space);
-  static ICCProfile FromSkColorSpace(sk_sp<SkColorSpace> color_space);
 
   // Create directly from profile data.
-  static ICCProfile FromData(const char* icc_profile, size_t size);
+  static ICCProfile FromData(const void* icc_profile, size_t size);
 
   // This will perform a potentially-lossy conversion to a more compact color
   // space representation.
-  ColorSpace GetColorSpace() const;
+  const ColorSpace& GetColorSpace() const;
 
   const std::vector<char>& GetData() const;
 
@@ -72,36 +67,25 @@
   static bool CachedProfilesNeedUpdate();
 #endif
 
-  enum class Type {
-    // This is not a valid profile.
-    INVALID,
-    // This is from a gfx::ColorSpace. This ensures that GetColorSpace returns
-    // the exact same object as was used to create this.
-    FROM_COLOR_SPACE,
-    // This was created from ICC profile data.
-    FROM_DATA,
-    LAST = FROM_DATA
-  };
-
  private:
+  // TODO(ccameron): Remove this function once its callerrs are gone.
+  static ICCProfile FromSkColorSpace(sk_sp<SkColorSpace> color_space);
   static bool IsValidProfileLength(size_t length);
-
-  Type type_ = Type::INVALID;
-  gfx::ColorSpace color_space_;
-  std::vector<char> data_;
+  void ComputeColorSpaceAndCache();
 
   // This globally identifies this ICC profile. It is used to look up this ICC
-  // profile from a ColorSpace object created from it.
+  // profile from a ColorSpace object created from it. The object is invalid if
+  // |id_| is zero.
   uint64_t id_ = 0;
+  std::vector<char> data_;
+
+  gfx::ColorSpace color_space_;
 
   FRIEND_TEST_ALL_PREFIXES(SimpleColorSpace, BT709toSRGBICC);
   FRIEND_TEST_ALL_PREFIXES(SimpleColorSpace, GetColorSpace);
   friend int ::LLVMFuzzerTestOneInput(const uint8_t*, size_t);
   friend class ColorSpace;
   friend struct IPC::ParamTraits<gfx::ICCProfile>;
-  friend struct IPC::ParamTraits<gfx::ICCProfile::Type>;
-  friend struct mojo::StructTraits<gfx::mojom::ICCProfileDataView,
-                                   gfx::ICCProfile>;
 };
 
 }  // namespace gfx
diff --git a/ui/gfx/ipc/color/gfx_param_traits.cc b/ui/gfx/ipc/color/gfx_param_traits.cc
index 6129e1d..657adc32 100644
--- a/ui/gfx/ipc/color/gfx_param_traits.cc
+++ b/ui/gfx/ipc/color/gfx_param_traits.cc
@@ -16,10 +16,10 @@
   GetParamSize(s, p.matrix_);
   GetParamSize(s, p.range_);
   GetParamSize(s, p.icc_profile_id_);
-  if (p.primaries_ == gfx::ColorSpace::PrimaryID::CUSTOM) {
-    for (int i = 0; i < 12; i++)
-      GetParamSize(s, p.custom_primary_matrix_[i]);
-  }
+  if (p.primaries_ == gfx::ColorSpace::PrimaryID::CUSTOM)
+    s->AddData(sizeof(p.custom_primary_matrix_));
+  if (p.transfer_ == gfx::ColorSpace::TransferID::CUSTOM)
+    s->AddData(sizeof(p.custom_transfer_params_));
 }
 
 void ParamTraits<gfx::ColorSpace>::Write(base::Pickle* m,
@@ -30,8 +30,12 @@
   WriteParam(m, p.range_);
   WriteParam(m, p.icc_profile_id_);
   if (p.primaries_ == gfx::ColorSpace::PrimaryID::CUSTOM) {
-    for (int i = 0; i < 12; i++)
-      WriteParam(m, p.custom_primary_matrix_[i]);
+    m->WriteBytes(reinterpret_cast<const char*>(p.custom_primary_matrix_),
+                  sizeof(p.custom_primary_matrix_));
+  }
+  if (p.transfer_ == gfx::ColorSpace::TransferID::CUSTOM) {
+    m->WriteBytes(reinterpret_cast<const char*>(p.custom_transfer_params_),
+                  sizeof(p.custom_transfer_params_));
   }
 }
 
@@ -48,12 +52,18 @@
     return false;
   if (!ReadParam(m, iter, &r->icc_profile_id_))
     return false;
-
   if (r->primaries_ == gfx::ColorSpace::PrimaryID::CUSTOM) {
-    for (int i = 0; i < 12; i++) {
-      if (!ReadParam(m, iter, r->custom_primary_matrix_ + i))
-        return false;
-    }
+    const char* data = nullptr;
+    if (!iter->ReadBytes(&data, sizeof(r->custom_primary_matrix_)))
+      return false;
+    memcpy(r->custom_primary_matrix_, data, sizeof(r->custom_primary_matrix_));
+  }
+  if (r->transfer_ == gfx::ColorSpace::TransferID::CUSTOM) {
+    const char* data = nullptr;
+    if (!iter->ReadBytes(&data, sizeof(r->custom_transfer_params_)))
+      return false;
+    memcpy(r->custom_transfer_params_, data,
+           sizeof(r->custom_transfer_params_));
   }
   return true;
 }
@@ -63,6 +73,36 @@
   l->append("<gfx::ColorSpace>");
 }
 
+void ParamTraits<gfx::ICCProfile>::GetSize(base::PickleSizer* s,
+                                           const gfx::ICCProfile& p) {
+  GetParamSize(s, p.id_);
+  GetParamSize(s, p.data_);
+}
+
+void ParamTraits<gfx::ICCProfile>::Write(base::Pickle* m,
+                                         const gfx::ICCProfile& p) {
+  WriteParam(m, p.id_);
+  WriteParam(m, p.data_);
+}
+
+bool ParamTraits<gfx::ICCProfile>::Read(const base::Pickle* m,
+                                        base::PickleIterator* iter,
+                                        gfx::ICCProfile* r) {
+  if (!ReadParam(m, iter, &r->id_))
+    return false;
+  if (!ReadParam(m, iter, &r->data_))
+    return false;
+  // Ensure that this entry is added to the global ICC profile cache, if it
+  // is not there already.
+  r->ComputeColorSpaceAndCache();
+  return true;
+}
+
+void ParamTraits<gfx::ICCProfile>::Log(const gfx::ICCProfile& p,
+                                       std::string* l) {
+  l->append("<gfx::ICCProfile>");
+}
+
 }  // namespace IPC
 
 // Generate param traits size methods.
diff --git a/ui/gfx/ipc/color/gfx_param_traits.h b/ui/gfx/ipc/color/gfx_param_traits.h
index 81b6301..8021258 100644
--- a/ui/gfx/ipc/color/gfx_param_traits.h
+++ b/ui/gfx/ipc/color/gfx_param_traits.h
@@ -29,6 +29,17 @@
   static void Log(const param_type& p, std::string* l);
 };
 
+template <>
+struct GFX_IPC_COLOR_EXPORT ParamTraits<gfx::ICCProfile> {
+  typedef gfx::ICCProfile param_type;
+  static void GetSize(base::PickleSizer* s, const param_type& p);
+  static void Write(base::Pickle* m, const param_type& p);
+  static bool Read(const base::Pickle* m,
+                   base::PickleIterator* iter,
+                   param_type* r);
+  static void Log(const param_type& p, std::string* l);
+};
+
 }  // namespace IPC
 
 #endif  // UI_GFX_IPC_COLOR_GFX_PARAM_TRAITS_H_
diff --git a/ui/gfx/ipc/color/gfx_param_traits_macros.h b/ui/gfx/ipc/color/gfx_param_traits_macros.h
index fcc8243..7c1ba7c6 100644
--- a/ui/gfx/ipc/color/gfx_param_traits_macros.h
+++ b/ui/gfx/ipc/color/gfx_param_traits_macros.h
@@ -24,15 +24,6 @@
 IPC_ENUM_TRAITS_MAX_VALUE(gfx::ColorSpace::RangeID,
                           gfx::ColorSpace::RangeID::LAST);
 
-IPC_ENUM_TRAITS_MAX_VALUE(gfx::ICCProfile::Type, gfx::ICCProfile::Type::LAST);
-
-IPC_STRUCT_TRAITS_BEGIN(gfx::ICCProfile)
-  IPC_STRUCT_TRAITS_MEMBER(type_)
-  IPC_STRUCT_TRAITS_MEMBER(color_space_)
-  IPC_STRUCT_TRAITS_MEMBER(data_)
-  IPC_STRUCT_TRAITS_MEMBER(id_)
-IPC_STRUCT_TRAITS_END()
-
 #undef IPC_MESSAGE_EXPORT
 #define IPC_MESSAGE_EXPORT
 
diff --git a/ui/gfx/mojo/OWNERS b/ui/gfx/mojo/OWNERS
index e7a266d..34d76d9 100644
--- a/ui/gfx/mojo/OWNERS
+++ b/ui/gfx/mojo/OWNERS
@@ -5,3 +5,5 @@
 per-file *.mojom=file://ipc/SECURITY_OWNERS
 per-file *_struct_traits*.*=set noparent
 per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *.typemap=set noparent
+per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/ui/gfx/mojo/icc_profile.mojom b/ui/gfx/mojo/icc_profile.mojom
index 72aaba5..62684b4 100644
--- a/ui/gfx/mojo/icc_profile.mojom
+++ b/ui/gfx/mojo/icc_profile.mojom
@@ -6,11 +6,5 @@
 
 import "ui/gfx/mojo/color_space.mojom";
 
-struct ICCProfile {
-  [Native]
-  enum Type;
-  gfx.mojom.ColorSpace color_space;
-  Type type;
-  string data;
-  uint64 id;
-};
+[Native]
+struct ICCProfile;
diff --git a/ui/gfx/mojo/icc_profile.typemap b/ui/gfx/mojo/icc_profile.typemap
index fd74b34d..33776951d 100644
--- a/ui/gfx/mojo/icc_profile.typemap
+++ b/ui/gfx/mojo/icc_profile.typemap
@@ -4,17 +4,12 @@
 
 mojom = "//ui/gfx/mojo/icc_profile.mojom"
 public_headers = [ "//ui/gfx/icc_profile.h" ]
-traits_headers = [ "//ui/gfx/mojo/icc_profile_struct_traits.h" ]
-sources = [
-  "//ui/gfx/mojo/icc_profile_struct_traits.cc",
-]
+traits_headers = [ "//ui/gfx/ipc/color/gfx_param_traits.h" ]
 public_deps = [
+  "//ipc",
   "//ui/gfx",
 ]
 deps = [
   "//ui/gfx/ipc/color",
 ]
-type_mappings = [
-  "gfx.mojom.ICCProfile.Type=gfx::ICCProfile::Type",
-  "gfx.mojom.ICCProfile=gfx::ICCProfile",
-]
+type_mappings = [ "gfx.mojom.ICCProfile=gfx::ICCProfile" ]
diff --git a/ui/gfx/mojo/icc_profile_struct_traits.cc b/ui/gfx/mojo/icc_profile_struct_traits.cc
deleted file mode 100644
index e612f36..0000000
--- a/ui/gfx/mojo/icc_profile_struct_traits.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/gfx/mojo/icc_profile_struct_traits.h"
-
-#include <algorithm>
-
-#include "mojo/public/cpp/bindings/string_data_view.h"
-
-namespace mojo {
-
-using Traits = StructTraits<gfx::mojom::ICCProfileDataView, gfx::ICCProfile>;
-
-// static
-bool Traits::Read(gfx::mojom::ICCProfileDataView data, gfx::ICCProfile* out) {
-  if (!data.ReadType(&out->type_))
-    return false;
-  if (!data.ReadColorSpace(&out->color_space_))
-    return false;
-  out->id_ = data.id();
-
-  mojo::StringDataView view;
-  data.GetDataDataView(&view);
-  out->data_.resize(view.size());
-  std::copy(view.storage(), view.storage() + view.size(), out->data_.begin());
-  return true;
-}
-
-}  // namespace mojo
diff --git a/ui/gfx/mojo/icc_profile_struct_traits.h b/ui/gfx/mojo/icc_profile_struct_traits.h
deleted file mode 100644
index b80e1e87..0000000
--- a/ui/gfx/mojo/icc_profile_struct_traits.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_GFX_MOJO_ICC_PROFILE_STRUCT_TRAITS_H_
-#define UI_GFX_MOJO_ICC_PROFILE_STRUCT_TRAITS_H_
-
-#include <algorithm>
-#include <memory>
-
-#include "base/strings/string_piece.h"
-#include "mojo/public/cpp/bindings/struct_traits.h"
-#include "ui/gfx/icc_profile.h"
-#include "ui/gfx/ipc/color/gfx_param_traits.h"
-#include "ui/gfx/mojo/icc_profile.mojom.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<gfx::mojom::ICCProfileDataView, gfx::ICCProfile> {
-  static gfx::ICCProfile::Type type(const gfx::ICCProfile& profile) {
-    return profile.type_;
-  }
-  static gfx::ColorSpace color_space(const gfx::ICCProfile& profile) {
-    return profile.color_space_;
-  }
-  static base::StringPiece data(const gfx::ICCProfile& profile) {
-    return base::StringPiece(profile.data_.data(), profile.data_.size());
-  }
-  static uint64_t id(const gfx::ICCProfile& profile) { return profile.id_; }
-
-  static bool Read(gfx::mojom::ICCProfileDataView data,
-                   gfx::ICCProfile* profile);
-};
-
-}  // namespace mojo
-
-#endif  // UI_GFX_MOJO_ICC_PROFILE_STRUCT_TRAITS_H_
diff --git a/ui/ozone/platform/drm/BUILD.gn b/ui/ozone/platform/drm/BUILD.gn
index abb3815..d760b3ee 100644
--- a/ui/ozone/platform/drm/BUILD.gn
+++ b/ui/ozone/platform/drm/BUILD.gn
@@ -5,18 +5,8 @@
 import("//build/config/linux/pkg_config.gni")
 import("//ui/ozone/ozone.gni")
 
-declare_args() {
-  use_drm_atomic = true
-}
-
 visibility = [ "//ui/ozone/*" ]
 
-config("drm_atomic") {
-  if (use_drm_atomic) {
-    defines = [ "USE_DRM_ATOMIC" ]
-  }
-}
-
 source_set("gbm") {
   sources = [
     "client_native_pixmap_factory_gbm.cc",
@@ -75,8 +65,12 @@
     "gpu/hardware_display_controller.h",
     "gpu/hardware_display_plane.cc",
     "gpu/hardware_display_plane.h",
+    "gpu/hardware_display_plane_atomic.cc",
+    "gpu/hardware_display_plane_atomic.h",
     "gpu/hardware_display_plane_manager.cc",
     "gpu/hardware_display_plane_manager.h",
+    "gpu/hardware_display_plane_manager_atomic.cc",
+    "gpu/hardware_display_plane_manager_atomic.h",
     "gpu/hardware_display_plane_manager_legacy.cc",
     "gpu/hardware_display_plane_manager_legacy.h",
     "gpu/inter_thread_messaging_proxy.cc",
@@ -150,21 +144,10 @@
   public_configs = [ "//third_party/khronos:khronos_headers" ]
 
   defines = [ "OZONE_IMPLEMENTATION" ]
-
-  if (use_drm_atomic) {
-    configs += [ ":drm_atomic" ]
-    sources += [
-      "gpu/hardware_display_plane_atomic.cc",
-      "gpu/hardware_display_plane_atomic.h",
-      "gpu/hardware_display_plane_manager_atomic.cc",
-      "gpu/hardware_display_plane_manager_atomic.h",
-    ]
-  }
 }
 
 source_set("gbm_unittests") {
   testonly = true
-  configs += [ ":drm_atomic" ]
   sources = [
     "gpu/drm_overlay_validator_unittest.cc",
     "gpu/drm_window_unittest.cc",
diff --git a/ui/ozone/platform/drm/common/scoped_drm_types.cc b/ui/ozone/platform/drm/common/scoped_drm_types.cc
index 05d0726..e8b7941 100644
--- a/ui/ozone/platform/drm/common/scoped_drm_types.cc
+++ b/ui/ozone/platform/drm/common/scoped_drm_types.cc
@@ -42,11 +42,9 @@
   drmModeFreeProperty(property);
 }
 
-#if defined(USE_DRM_ATOMIC)
 void DrmAtomicReqDeleter::operator()(drmModeAtomicReq* property) const {
   drmModeAtomicFree(property);
 }
-#endif  // defined(USE_DRM_ATOMIC)
 
 void DrmPropertyBlobDeleter::operator()(
     drmModePropertyBlobRes* property) const {
diff --git a/ui/ozone/platform/drm/common/scoped_drm_types.h b/ui/ozone/platform/drm/common/scoped_drm_types.h
index 3522842..93a7d4d 100644
--- a/ui/ozone/platform/drm/common/scoped_drm_types.h
+++ b/ui/ozone/platform/drm/common/scoped_drm_types.h
@@ -45,11 +45,9 @@
 struct DrmPropertyDeleter {
   void operator()(drmModePropertyRes* property) const;
 };
-#if defined(USE_DRM_ATOMIC)
 struct DrmAtomicReqDeleter {
   void operator()(drmModeAtomicReq* property) const;
 };
-#endif  // defined(USE_DRM_ATOMIC)
 struct DrmPropertyBlobDeleter {
   void operator()(drmModePropertyBlobRes* property) const;
 };
@@ -69,10 +67,8 @@
     ScopedDrmPlaneResPtr;
 typedef std::unique_ptr<drmModePropertyRes, DrmPropertyDeleter>
     ScopedDrmPropertyPtr;
-#if defined(USE_DRM_ATOMIC)
 typedef std::unique_ptr<drmModeAtomicReq, DrmAtomicReqDeleter>
     ScopedDrmAtomicReqPtr;
-#endif  // defined(USE_DRM_ATOMIC)
 typedef std::unique_ptr<drmModePropertyBlobRes, DrmPropertyBlobDeleter>
     ScopedDrmPropertyBlobPtr;
 typedef std::unique_ptr<drmModeFB, DrmFramebufferDeleter>
diff --git a/ui/ozone/platform/drm/gpu/drm_device.cc b/ui/ozone/platform/drm/gpu/drm_device.cc
index 6dff88e..438edaf 100644
--- a/ui/ozone/platform/drm/gpu/drm_device.cc
+++ b/ui/ozone/platform/drm/gpu/drm_device.cc
@@ -23,11 +23,9 @@
 #include "third_party/skia/include/core/SkImageInfo.h"
 #include "ui/display/types/gamma_ramp_rgb_entry.h"
 #include "ui/ozone/platform/drm/common/drm_util.h"
+#include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h"
 #include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h"
 
-#if defined(USE_DRM_ATOMIC)
-#include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h"
-#endif
 
 namespace ui {
 
@@ -411,11 +409,9 @@
     return false;
   }
 
-#if defined(USE_DRM_ATOMIC)
   // Use atomic only if the build, kernel & flags all allow it.
   if (use_atomic && SetCapability(DRM_CLIENT_CAP_ATOMIC, 1))
     plane_manager_.reset(new HardwareDisplayPlaneManagerAtomic());
-#endif  // defined(USE_DRM_ATOMIC)
 
   if (!plane_manager_)
     plane_manager_.reset(new HardwareDisplayPlaneManagerLegacy());
@@ -661,7 +657,6 @@
                                  uint32_t flags,
                                  uint32_t crtc_count,
                                  const PageFlipCallback& callback) {
-#if defined(USE_DRM_ATOMIC)
   uint64_t id = 0;
   bool page_flip_event_requested = flags & DRM_MODE_PAGE_FLIP_EVENT;
 
@@ -675,7 +670,6 @@
 
     return true;
   }
-#endif  // defined(USE_DRM_ATOMIC)
   return false;
 }
 
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc b/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
index 34c62c1..e83d62e 100644
--- a/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
+++ b/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
@@ -67,7 +67,6 @@
                                  const gfx::Rect& plane_bounds,
                                  const gfx::Rect& window_bounds,
                                  HardwareDisplayController* controller) {
-  bool force_primary_format = false;
   uint32_t z_order = plane_z_order;
   // If Overlay completely covers primary and isn't transparent, try to find
   // optimal format w.r.t primary plane. This guarantees that optimal format
@@ -75,17 +74,8 @@
   if (plane_bounds == window_bounds &&
       !NeedsAlphaComposition(original_format)) {
     z_order = 0;
-#if !defined(USE_DRM_ATOMIC)
-    // Page flip can fail when trying to flip a buffer of format other than
-    // what was used during Modeset on non atomic kernels. There is no
-    // definitive way to query this.
-    force_primary_format = true;
-#endif
   }
 
-  if (force_primary_format)
-    return DRM_FORMAT_XRGB8888;
-
   // YUV is preferable format if supported.
   if (controller->IsFormatSupported(DRM_FORMAT_UYVY, z_order)) {
     return DRM_FORMAT_UYVY;
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.cc b/ui/ozone/platform/drm/gpu/drm_thread.cc
index ad941681..479e1a2d 100644
--- a/ui/ozone/platform/drm/gpu/drm_thread.cc
+++ b/ui/ozone/platform/drm/gpu/drm_thread.cc
@@ -89,10 +89,8 @@
 
 void DrmThread::Init() {
   bool use_atomic = false;
-#if defined(USE_DRM_ATOMIC)
   use_atomic = base::CommandLine::ForCurrentProcess()->HasSwitch(
       switches::kEnableDrmAtomic);
-#endif
 
   device_manager_.reset(
       new DrmDeviceManager(base::MakeUnique<GbmDeviceGenerator>(use_atomic)));
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
index 408d0d6ca..9734057 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
@@ -23,9 +23,7 @@
 }  // namespace
 
 HardwareDisplayPlaneList::HardwareDisplayPlaneList() {
-#if defined(USE_DRM_ATOMIC)
   atomic_property_set.reset(drmModeAtomicAlloc());
-#endif  // defined(USE_DRM_ATOMIC)
 }
 
 HardwareDisplayPlaneList::~HardwareDisplayPlaneList() {
@@ -222,9 +220,7 @@
 
   plane_list->plane_list.clear();
   plane_list->legacy_page_flips.clear();
-#if defined(USE_DRM_ATOMIC)
   plane_list->atomic_property_set.reset(drmModeAtomicAlloc());
-#endif
 }
 
 void HardwareDisplayPlaneManager::BeginFrame(
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
index 3a48948..800aa5a 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
@@ -62,9 +62,7 @@
   // pageflipping.
   std::vector<PageFlipInfo> legacy_page_flips;
 
-#if defined(USE_DRM_ATOMIC)
   ScopedDrmAtomicReqPtr atomic_property_set;
-#endif  // defined(USE_DRM_ATOMIC)
 };
 
 class HardwareDisplayPlaneManager {
diff --git a/ui/views/cocoa/bridged_content_view.mm b/ui/views/cocoa/bridged_content_view.mm
index 3afe6232..1796fff 100644
--- a/ui/views/cocoa/bridged_content_view.mm
+++ b/ui/views/cocoa/bridged_content_view.mm
@@ -837,7 +837,8 @@
   if (!hostedView_)
     return;
 
-  const gfx::Point locationInContent = ui::EventLocationFromNative(theEvent);
+  const gfx::Point locationInContent =
+      gfx::ToFlooredPoint(ui::EventLocationFromNative(theEvent));
   views::View* target = hostedView_->GetEventHandlerForPoint(locationInContent);
   if (!target)
     return;
diff --git a/ui/views/mus/desktop_window_tree_host_mus.cc b/ui/views/mus/desktop_window_tree_host_mus.cc
index 9cff6ce..02cf6376 100644
--- a/ui/views/mus/desktop_window_tree_host_mus.cc
+++ b/ui/views/mus/desktop_window_tree_host_mus.cc
@@ -406,9 +406,12 @@
   SetBoundsInDIP(screen_bounds);
 }
 
-void DesktopWindowTreeHostMus::StackAbove(aura::Window* window) {
-  // TODO: implement window stacking, http://crbug.com/663617.
-  NOTIMPLEMENTED();
+void DesktopWindowTreeHostMus::StackAbove(aura::Window* relative) {
+  // Windows and X11 check for |relative| being nullptr and fail silently. It
+  // also looks like |relative| is usually multiple children deep in the root
+  // window, which we must pass instead.
+  if (relative && relative->GetRootWindow())
+    WindowTreeHostMus::StackAbove(relative->GetRootWindow());
 }
 
 void DesktopWindowTreeHostMus::StackAtTop() {
diff --git a/ui/views/mus/desktop_window_tree_host_mus_unittest.cc b/ui/views/mus/desktop_window_tree_host_mus_unittest.cc
index a2609df..1620c58 100644
--- a/ui/views/mus/desktop_window_tree_host_mus_unittest.cc
+++ b/ui/views/mus/desktop_window_tree_host_mus_unittest.cc
@@ -184,6 +184,20 @@
   waiter.Wait();
 }
 
+TEST_F(DesktopWindowTreeHostMusTest, StackAbove) {
+  std::unique_ptr<Widget> widget1(CreateWidget(nullptr));
+  widget1->Show();
+
+  std::unique_ptr<Widget> widget2(CreateWidget(nullptr));
+  widget2->Show();
+
+  aura::test::ChangeCompletionWaiter waiter(
+      MusClient::Get()->window_tree_client(),
+      aura::ChangeType::REORDER, true);
+  widget1->StackAboveWidget(widget2.get());
+  waiter.Wait();
+}
+
 TEST_F(DesktopWindowTreeHostMusTest, TransientParentWiredToHostWindow) {
   std::unique_ptr<Widget> widget1(CreateWidget());
   widget1->Show();
diff --git a/ui/views/mus/mus_client.cc b/ui/views/mus/mus_client.cc
index 2a73231..2e23362 100644
--- a/ui/views/mus/mus_client.cc
+++ b/ui/views/mus/mus_client.cc
@@ -151,6 +151,9 @@
       mojo::ConvertTo<std::vector<uint8_t>>(
           static_cast<int32_t>(init_params.type));
 
+  properties[ui::mojom::WindowManager::kFocusable_InitProperty] =
+      mojo::ConvertTo<std::vector<uint8_t>>(init_params.CanActivate());
+
   if (!init_params.bounds.IsEmpty()) {
     properties[ui::mojom::WindowManager::kBounds_InitProperty] =
         mojo::ConvertTo<std::vector<uint8_t>>(init_params.bounds);
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index 00081416..4d0e7cf9 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -142,6 +142,14 @@
 Widget::InitParams::~InitParams() {
 }
 
+bool Widget::InitParams::CanActivate() const {
+  if (activatable != InitParams::ACTIVATABLE_DEFAULT)
+    return activatable == InitParams::ACTIVATABLE_YES;
+  return type != InitParams::TYPE_CONTROL && type != InitParams::TYPE_POPUP &&
+         type != InitParams::TYPE_MENU && type != InitParams::TYPE_TOOLTIP &&
+         type != InitParams::TYPE_DRAG;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Widget, public:
 
@@ -309,20 +317,9 @@
   if (params.opacity == views::Widget::InitParams::INFER_OPACITY)
     params.opacity = views::Widget::InitParams::OPAQUE_WINDOW;
 
-  bool can_activate = false;
-  if (params.activatable != InitParams::ACTIVATABLE_DEFAULT) {
-    can_activate = (params.activatable == InitParams::ACTIVATABLE_YES);
-  } else if (params.type != InitParams::TYPE_CONTROL &&
-             params.type != InitParams::TYPE_POPUP &&
-             params.type != InitParams::TYPE_MENU &&
-             params.type != InitParams::TYPE_TOOLTIP &&
-             params.type != InitParams::TYPE_DRAG) {
-    can_activate = true;
-    params.activatable = InitParams::ACTIVATABLE_YES;
-  } else {
-    can_activate = false;
-    params.activatable = InitParams::ACTIVATABLE_NO;
-  }
+  bool can_activate = params.CanActivate();
+  params.activatable =
+      can_activate ? InitParams::ACTIVATABLE_YES : InitParams::ACTIVATABLE_NO;
 
   widget_delegate_ = params.delegate ?
       params.delegate : new DefaultWidgetDelegate(this);
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h
index a9861ec2..33c0656 100644
--- a/ui/views/widget/widget.h
+++ b/ui/views/widget/widget.h
@@ -214,6 +214,10 @@
     InitParams(const InitParams& other);
     ~InitParams();
 
+    // Returns the activatablity based on |activatable|, but also handles the
+    // case where |activatable| is |ACTIVATABLE_DEFAULT|.
+    bool CanActivate() const;
+
     Type type;
     // If null, a default implementation will be constructed. The default
     // implementation deletes itself when the Widget closes.