diff --git a/DEPS b/DEPS
index 74f3749..1929245 100644
--- a/DEPS
+++ b/DEPS
@@ -74,7 +74,7 @@
   # 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': 'a0985d960fb7c2010274a0fb4a8aa771ece6dc1f',
+  'skia_revision': 'ea6138253bda6edef21c3a51d47f893c79f29ef8',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -634,7 +634,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '05591bbeae6592fd924caec8e728a4ea86cbb8c9',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '87ed4487e40dad8c0c5d415b95f3c40c5b4d2db4', # commit position 20628
+    Var('webrtc_git') + '/src.git' + '@' + 'a9f469b2184dfdb723fc23e90076c37916f08157', # commit position 20628
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
index df7faee..de46dd6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
@@ -7,7 +7,6 @@
 import android.app.Activity;
 import android.text.TextUtils;
 
-import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.chrome.browser.ChromeVersionInfo;
@@ -78,9 +77,9 @@
         // Promo can be shown at most once every 2 Chrome major versions.
         if (currentMajorVersion < lastPromoMajorVersion + 2) return false;
 
-        // Don't show if account list hasn't changed since the last time promo was shown.
+        // Don't show if no new accounts have been added after the last time promo was shown.
         Set<String> previousAccountNames = preferenceManager.getSigninPromoLastAccountNames();
-        return !ApiCompatibilityUtils.objectEquals(previousAccountNames, accountNames);
+        return previousAccountNames == null || !previousAccountNames.containsAll(accountNames);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
index 0fd63f4d..0ca9de58 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -517,7 +517,7 @@
 
             if (dpPerMs > SHEET_SWIPE_MAX_DP_PER_MS) {
                 if (shouldRecordHistogram && !mIsSwipeVelocityRecorded) {
-                    recordSwipeVelocity("Android.ChromeHome.OpenSwipeVelocity.Fail",
+                    recordSwipeVelocity("Android.ChromeHome.OpenSheetVelocity.Fail",
                             (int) mLastSheetOpenMicrosPerDp);
                     mIsSwipeVelocityRecorded = true;
                 }
@@ -526,7 +526,7 @@
             }
 
             if (shouldRecordHistogram && !mIsSwipeVelocityRecorded) {
-                recordSwipeVelocity("Android.ChromeHome.OpenSwipeVelocity.Success",
+                recordSwipeVelocity("Android.ChromeHome.OpenSheetVelocity.Success",
                         (int) mLastSheetOpenMicrosPerDp);
                 mIsSwipeVelocityRecorded = true;
             }
@@ -597,7 +597,7 @@
                         || reason == StateChangeReason.BACK_PRESS
                         || reason == StateChangeReason.TAP_SCRIM;
                 if (mShouldRecordSwipeVelocity && shouldRecordClose) {
-                    recordSwipeVelocity("Android.ChromeHome.OpenSwipeVelocity.NoNavigation",
+                    recordSwipeVelocity("Android.ChromeHome.OpenSheetVelocity.NoNavigation",
                             (int) mLastSheetOpenMicrosPerDp);
                 }
                 mShouldRecordSwipeVelocity = false;
@@ -624,7 +624,7 @@
              */
             private void recordVelocityForNavigation() {
                 if (!mShouldRecordSwipeVelocity) return;
-                recordSwipeVelocity("Android.ChromeHome.OpenSwipeVelocity.Navigation",
+                recordSwipeVelocity("Android.ChromeHome.OpenSheetVelocity.Navigation",
                         (int) mLastSheetOpenMicrosPerDp);
                 mShouldRecordSwipeVelocity = false;
             }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninPromoUtilTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninPromoUtilTest.java
index 773944b..bb8b02f 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninPromoUtilTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninPromoUtilTest.java
@@ -22,8 +22,6 @@
 import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
 import org.chromium.testing.local.LocalRobolectricTestRunner;
 
-import java.util.Set;
-
 /** Tests for {@link SigninPromoUtil}. */
 @RunWith(LocalRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
@@ -79,18 +77,38 @@
     }
 
     @Test
-    public void whenAllConditionsAreMetShouldReturnTrue() {
+    public void whenNoAccountListStoredShouldReturnTrue() {
         when(mPreferenceManager.getSigninPromoLastShownVersion()).thenReturn(40);
+        // Old implementation hasn't been storing account list
+        when(mPreferenceManager.getSigninPromoLastAccountNames()).thenReturn(null);
         Assert.assertTrue(SigninPromoUtil.shouldLaunchSigninPromo(
                 mPreferenceManager, 42, false, false, ImmutableSet.of("test@gmail.com")));
     }
 
     @Test
+    public void whenHasNewAccountShouldReturnTrue() {
+        when(mPreferenceManager.getSigninPromoLastShownVersion()).thenReturn(40);
+        when(mPreferenceManager.getSigninPromoLastAccountNames())
+                .thenReturn(ImmutableSet.of("test@gmail.com"));
+        Assert.assertTrue(SigninPromoUtil.shouldLaunchSigninPromo(mPreferenceManager, 42, false,
+                false, ImmutableSet.of("test@gmail.com", "test2@gmail.com")));
+    }
+
+    @Test
     public void whenAccountListUnchangedShouldReturnFalse() {
         when(mPreferenceManager.getSigninPromoLastShownVersion()).thenReturn(40);
-        Set<String> accountNames = ImmutableSet.of("test@gmail.com");
-        when(mPreferenceManager.getSigninPromoLastAccountNames()).thenReturn(accountNames);
+        when(mPreferenceManager.getSigninPromoLastAccountNames())
+                .thenReturn(ImmutableSet.of("test@gmail.com"));
         Assert.assertFalse(SigninPromoUtil.shouldLaunchSigninPromo(
-                mPreferenceManager, 42, false, false, accountNames));
+                mPreferenceManager, 42, false, false, ImmutableSet.of("test@gmail.com")));
+    }
+
+    @Test
+    public void whenNoNewAccountsShouldReturnFalse() {
+        when(mPreferenceManager.getSigninPromoLastShownVersion()).thenReturn(40);
+        when(mPreferenceManager.getSigninPromoLastAccountNames())
+                .thenReturn(ImmutableSet.of("test@gmail.com", "test2@gmail.com"));
+        Assert.assertFalse(SigninPromoUtil.shouldLaunchSigninPromo(
+                mPreferenceManager, 42, false, false, ImmutableSet.of("test2@gmail.com")));
     }
 }
diff --git a/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc b/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc
index c47f338..ea5cf7b8 100644
--- a/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc
+++ b/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc
@@ -7,6 +7,8 @@
 #include "base/strings/pattern.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/accessibility/speech_monitor.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_window.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/notification_details.h"
@@ -40,6 +42,20 @@
   SpeechMonitor speech_monitor_;
   std::unique_ptr<ui::test::EventGenerator> generator_;
 
+  void ActivateSelectToSpeakInWindowBounds(std::string url) {
+    ui_test_utils::NavigateToURL(browser(), GURL(url));
+    gfx::Rect bounds = browser()->window()->GetBounds();
+
+    // Hold down Search and click a few pixels into the window bounds.
+    generator_->PressKey(ui::VKEY_LWIN, 0 /* flags */);
+    generator_->MoveMouseTo(bounds.x() + 8, bounds.y() + 50);
+    generator_->PressLeftButton();
+    generator_->MoveMouseTo(bounds.x() + bounds.width() - 8,
+                            bounds.y() + bounds.height() - 8);
+    generator_->ReleaseLeftButton();
+    generator_->ReleaseKey(ui::VKEY_LWIN, 0 /* flags */);
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(SelectToSpeakTest);
 };
@@ -59,4 +75,80 @@
       base::MatchPattern(speech_monitor_.GetNextUtterance(), "Status tray*"));
 }
 
+IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, SearchLocksToSelectToSpeakMode) {
+  ui_test_utils::NavigateToURL(browser(), GURL("data:text/html;charset=utf-8,"
+                                               "<p>This is some text</p>"));
+  gfx::Rect bounds = browser()->window()->GetBounds();
+
+  // Hold click Search, then and click a few pixels into the window bounds.
+  generator_->PressKey(ui::VKEY_LWIN, 0 /* flags */);
+  generator_->ReleaseKey(ui::VKEY_LWIN, 0 /* flags */);
+
+  for (int i = 0; i < 2; ++i) {
+    // With the mouse only, have it speak a few times.
+    generator_->MoveMouseTo(bounds.x() + 8, bounds.y() + 50);
+    generator_->PressLeftButton();
+    generator_->MoveMouseTo(bounds.x() + bounds.width() - 8,
+                            bounds.y() + bounds.height() - 8);
+    generator_->ReleaseLeftButton();
+
+    EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(),
+                                   "This is some text*"));
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, SmoothlyReadsAcrossInlineUrl) {
+  // Make sure an inline URL is read smoothly.
+  ActivateSelectToSpeakInWindowBounds(
+      "data:text/html;charset=utf-8,<p>This is some text <a href=>with a"
+      " node</a> in the middle");
+  // Should combine nodes in a paragraph into one utterance.
+  // Includes some wildcards between words because there may be extra
+  // spaces. Spaces are not pronounced, so extra spaces do not impact output.
+  EXPECT_TRUE(
+      base::MatchPattern(speech_monitor_.GetNextUtterance(),
+                         "This is some text*with a node*in the middle*"));
+}
+
+IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, SmoothlyReadsAcrossMultipleLines) {
+  // Sentences spanning multiple lines.
+  ActivateSelectToSpeakInWindowBounds(
+      "data:text/html;charset=utf-8,<div style=\"width:100px\">This"
+      " is some text with a node in the middle");
+  // Should combine nodes in a paragraph into one utterance.
+  // Includes some wildcards between words because there may be extra
+  // spaces, for example at line wraps. Extra wildcards included to
+  // reduce flakyness in case wrapping is not consistent.
+  // Spaces are not pronounced, so extra spaces do not impact output.
+  EXPECT_TRUE(
+      base::MatchPattern(speech_monitor_.GetNextUtterance(),
+                         "This is some*text*with*a*node*in*the*middle*"));
+}
+
+IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, SmoothlyReadsAcrossFormattedText) {
+  // Bold or formatted text
+  ActivateSelectToSpeakInWindowBounds(
+      "data:text/html;charset=utf-8,<p>This is some text <b>with a node"
+      "</b> in the middle");
+
+  // Should combine nodes in a paragraph into one utterance.
+  // Includes some wildcards between words because there may be extra
+  // spaces. Spaces are not pronounced, so extra spaces do not impact output.
+  EXPECT_TRUE(
+      base::MatchPattern(speech_monitor_.GetNextUtterance(),
+                         "This is some text*with a node*in the middle*"));
+}
+
+IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, BreaksAtParagraphBounds) {
+  ActivateSelectToSpeakInWindowBounds(
+      "data:text/html;charset=utf-8,<div><p>First paragraph</p>"
+      "<p>Second paragraph</p></div>");
+
+  // Should keep each paragraph as its own utterance.
+  EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(),
+                                 "First paragraph*"));
+  EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(),
+                                 "Second paragraph*"));
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/accessibility/speech_monitor.cc b/chrome/browser/chromeos/accessibility/speech_monitor.cc
index a0cf87e6..14169e3 100644
--- a/chrome/browser/chromeos/accessibility/speech_monitor.cc
+++ b/chrome/browser/chromeos/accessibility/speech_monitor.cc
@@ -40,6 +40,14 @@
   return did_stop_;
 }
 
+void SpeechMonitor::BlockUntilStop() {
+  if (!did_stop_) {
+    loop_runner_ = new content::MessageLoopRunner();
+    loop_runner_->Run();
+    loop_runner_ = NULL;
+  }
+}
+
 bool SpeechMonitor::SkipChromeVoxMessage(const std::string& message) {
   while (true) {
     if (utterance_queue_.empty()) {
diff --git a/chrome/browser/chromeos/accessibility/speech_monitor.h b/chrome/browser/chromeos/accessibility/speech_monitor.h
index 3512ed9c..6888b8b6 100644
--- a/chrome/browser/chromeos/accessibility/speech_monitor.h
+++ b/chrome/browser/chromeos/accessibility/speech_monitor.h
@@ -32,6 +32,9 @@
   // Returns true if StopSpeaking() was called on TtsController.
   bool DidStop();
 
+  // Blocks until StopSpeaking() is called on TtsController.
+  void BlockUntilStop();
+
  private:
   // TtsPlatformImpl implementation.
   bool PlatformImplAvailable() override;
diff --git a/docs/accessibility.md b/docs/accessibility.md
index eef1344f..869e1d1 100644
--- a/docs/accessibility.md
+++ b/docs/accessibility.md
@@ -3,6 +3,10 @@
 * [Accessibility Overview](accessibility/overview.md)
 * [Accessibility Tests](accessibility/tests.md)
 
+## Cross-Platform
+
+* [Offscreen, Invisible and Size](accessibility/offscreen.md)
+
 ## Chrome OS
 
 * [ChromeVox for Developers](accessibility/chromevox.md)
diff --git a/docs/accessibility/offscreen.md b/docs/accessibility/offscreen.md
new file mode 100644
index 0000000..8658c7f6
--- /dev/null
+++ b/docs/accessibility/offscreen.md
@@ -0,0 +1,145 @@
+# Offscreen, Invisible and Size
+
+This document explains how Chrome interprets the guidelines to apply the labels
+Offscreen and Invisible to nodes, and how the bounding box is calculated.
+
+## Background
+
+In general, screen reading tools may be interested in all nodes regardless of
+whether they are presented to sighted users, but other Accessibility tools may
+care what is visible to sighted users.
+
+Specifically, tools like Select-to-Speak and Switch Access should not look at
+nodes which are “offscreen”, “invisible”, or size=(0,0), as these are not
+visible on the screen for mouse interactions. On the other hand, ChromeVox and
+other screen readers may care about some of those nodes, which allow developers
+to insert buttons visible only to users with a screen reader, or to navigate
+below the fold.
+
+## Offscreen
+In Chrome, we define Offscreen as:
+
+>Any object is offscreen if it is fully clipped or scrolled out of view by any
+of its ancestors so that it is not rendered on the screen.
+
+For example, the staticText node here is offscreen:
+```html
+<div style="width:0; height; 0; overflow: hidden">
+  This text should be marked "offscreen", although its parent is not.
+</div>
+```
+
+As background, [MSDN](https://msdn.microsoft.com/en-us/library/dd373609(VS.85).aspx)
+defines Offscreen as an object is not rendered, but not because it was
+programatically hidden:
+
+>The object is clipped or has scrolled out of view, but it is not
+programmatically hidden. If the user makes the viewport larger, more of the
+object will be visible on the computer screen.
+
+In Chrome, we interpret this to mean that an object is fully clipped or
+scrolled out of view by its parent or ancestors. The main difference is that
+we are being explicit that any ancestor clipping a node can make it offscreen,
+not just a rootWebArea or scrollable ancestor.
+
+### Technical Implementation
+Offscreen is calculated in [AXTree::RelativeToTreeBounds](https://cs.chromium.org/chromium/src/ui/accessibility/ax_tree.cc).
+In this function, we walk up the accessibility tree adjusting a node's bounding
+box to the frame of its ancestors. If the box is clipped because it lies
+outside an ancestor's bounds, and that ancestor clips its children (i.e.
+overflow:hidden, overflow:scroll, or it is a rootWebArea), offscreen is set to
+true.
+
+## Invisible
+A node is marked Invisible in Chrome if it is hidden programatically. In some
+cases, invisible nodes are simply excluded from the accessibility tree. Chrome
+defines invisible as:
+
+>Invisible means that a node or its ancestor is explicitly invisible.
+
+This is the same as the definition from [MSDN](https://msdn.microsoft.com/en-us/library/dd373609(VS.85).aspx):
+
+>The object is programmatically hidden.
+
+For example, these nodes are invisible:
+
+```html
+<div style="display:none">
+  This text should be marked 'invisible', along with its parent div.
+</div>
+
+<div style="visibility:hidden">
+  This text should also be marked 'invisible' along with its parent div.
+</div>
+
+<div style="opacity:0">
+  Opactiy zero is also treated as invisible.
+</div>
+```
+
+## Bounding box calculation
+A node's bounding box (location and size) are calculated based on its
+intrinsic width, height and location, and the sizes of its ancestors.
+We calculate size clipped by ancestors by default, but can also expose an
+unclipped size through the [automation API](https://developer.chrome.com/extensions/automation).
+
+The unclipped bounding box is helpful if you want to know the current
+coordinates of an element that's scrolled out of view, so you know how
+much to scroll to bring it in view.
+
+The clipped bounding box is helpful if you want to draw a visible bounding
+box around the element on the screen. Clipping the bounding box helps
+sighted users understand what container the element is in, even if it's
+not currently visible. Without clipping you end up with elements floating
+outside of windows.
+
+### Technical implementation
+A node's location and size are calculated in[AXTree::RelativeToTreeBounds](https://cs.chromium.org/chromium/src/ui/accessibility/ax_tree.cc),
+and so closely tied to the offscreen calculation. In this function, we walk up
+the accessibility tree adjusting a node's bounding box to the frame of its
+ancestors.
+
+In general, this calculation is straight forward. But there are several edge
+cases:
+
+* If a node has no intrinsic size, its size will be taken from the union of
+its children.
+
+```html
+    <!-- The outer div here has no size, so we use its child for its bounding box -->
+    <div style="visibility:hidden" aria-hidden=false>
+      <div style="visibility:visible">
+        Visible text
+      </div>
+    </div>
+```
+
+* If a node still has no size after that union, its bounds will be set to the
+size of the nearest ancestor which has size. However, this node will be marked
+`offscreen`, because it isn't visible to the user.
+
+    * This is useful for exposing nodes to screen reader users.
+
+In addition, [AXTree::RelativeToTreeBounds](https://cs.chromium.org/chromium/src/ui/accessibility/ax_tree.cc)
+is used to determine how location and size may be clipped by ancestors,
+allowing bounding boxes to reflect the location of a node clipped to its
+ancestors.
+
+* If a node is fully clipped by its ancestors such that the intersection of its
+bounds and an ancestor's bounds are size 0, it will be pushed to the nearest
+edge of the ancestor with width 1 or height 1.
+
+    * We use width and height 1 instead of 0 to distinguish between empty or
+    unknown sized nodes vs known small or clipped sized nodes.
+
+Both clipped and unclipped location and size are exposed through the
+[Chrome automation API](https://developer.chrome.com/extensions/automation).
+
+* `location` is the global location of a node as clipped by its ancestors. If
+a node is fully scrolled off a rootWebArea in X, for example, its location will
+be the height of the rootWebArea, and its height will be 1. The Y position and width will be unchanged.
+
+* `unclippedLocation` is the global location of a node ignoring any clipping
+by ancestors. If a node is fully scrolled off a rootWebArea in X, for example,
+its location will simply be larger than the height of the rootWebArea, and its
+size will also be unchanged.
diff --git a/ios/web/navigation/navigation_manager_delegate.h b/ios/web/navigation/navigation_manager_delegate.h
index 3266aa34..2d7698bc 100644
--- a/ios/web/navigation/navigation_manager_delegate.h
+++ b/ios/web/navigation/navigation_manager_delegate.h
@@ -68,6 +68,11 @@
   // Returns a CRWWebViewNavigationProxy protocol that can be used to access
   // navigation related functions on the main WKWebView.
   virtual id<CRWWebViewNavigationProxy> GetWebViewNavigationProxy() const = 0;
+
+  // Instructs the delegate to remove the underlying web view. The only use case
+  // currently is to clear back-forward history in web view before restoring
+  // session history.
+  virtual void RemoveWebView() = 0;
 };
 
 }  // namespace web
diff --git a/ios/web/navigation/navigation_manager_impl_unittest.mm b/ios/web/navigation/navigation_manager_impl_unittest.mm
index 9f8b94f3..a642c9c5 100644
--- a/ios/web/navigation/navigation_manager_impl_unittest.mm
+++ b/ios/web/navigation/navigation_manager_impl_unittest.mm
@@ -81,6 +81,7 @@
   MOCK_METHOD1(OnNavigationItemsPruned, void(size_t));
   MOCK_METHOD0(OnNavigationItemChanged, void());
   MOCK_METHOD1(OnNavigationItemCommitted, void(const LoadCommittedDetails&));
+  MOCK_METHOD0(RemoveWebView, void());
 
  private:
   WebState* GetWebState() override { return nullptr; }
diff --git a/ios/web/navigation/wk_based_navigation_manager_impl.mm b/ios/web/navigation/wk_based_navigation_manager_impl.mm
index d21ed98..f582e51 100644
--- a/ios/web/navigation/wk_based_navigation_manager_impl.mm
+++ b/ios/web/navigation/wk_based_navigation_manager_impl.mm
@@ -361,12 +361,20 @@
 void WKBasedNavigationManagerImpl::Restore(
     int last_committed_item_index,
     std::vector<std::unique_ptr<NavigationItem>> items) {
-  DCHECK(GetItemCount() == 0 && !GetPendingItem());
   DCHECK_LT(last_committed_item_index, static_cast<int>(items.size()));
   DCHECK(items.empty() || last_committed_item_index >= 0);
   if (items.empty())
     return;
 
+  DiscardNonCommittedItems();
+  if (GetItemCount() > 0) {
+    delegate_->RemoveWebView();
+  }
+  DCHECK_EQ(0, GetItemCount());
+  pending_item_index_ = -1;
+  previous_item_index_ = -1;
+  last_committed_item_index_ = -1;
+
   // This function restores session history by loading a magic local file
   // (restore_session.html) into the web view. The session history is encoded
   // in the query parameter. When loaded, restore_session.html parses the
diff --git a/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm b/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm
index 9f36b622..1a29a13 100644
--- a/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm
+++ b/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm
@@ -61,6 +61,10 @@
 class MockNavigationManagerDelegate : public NavigationManagerDelegate {
  public:
   void SetWebViewNavigationProxy(id web_view) { mock_web_view_ = web_view; }
+  void RemoveWebView() override {
+    // Simulate removing the web view.
+    mock_web_view_ = nil;
+  }
 
   MOCK_METHOD0(ClearTransientContent, void());
   MOCK_METHOD0(RecordPageStateInNavigationItem, void());
@@ -590,6 +594,66 @@
       session_json);
 }
 
+// Tests that restoring session replaces existing history in navigation manager.
+TEST_F(WKBasedNavigationManagerTest, RestoreSessionResetsHistory) {
+  EXPECT_EQ(-1, manager_->GetPendingItemIndex());
+  EXPECT_EQ(-1, manager_->GetPreviousItemIndex());
+  EXPECT_EQ(-1, manager_->GetLastCommittedItemIndex());
+
+  // Sets up the navigation history with 2 entries, and a pending back-forward
+  // navigation so that last_committed_item_index is 1, pending_item_index is 0,
+  // and previous_item_index is 0. Basically, none of them is -1.
+  manager_->AddPendingItem(
+      GURL("http://www.url.com/0"), Referrer(), ui::PAGE_TRANSITION_TYPED,
+      web::NavigationInitiationType::USER_INITIATED,
+      web::NavigationManager::UserAgentOverrideOption::INHERIT);
+  [mock_wk_list_ setCurrentURL:@"http://www.url.com/0"];
+  manager_->CommitPendingItem();
+
+  manager_->AddPendingItem(
+      GURL("http://www.url.com/1"), Referrer(), ui::PAGE_TRANSITION_TYPED,
+      web::NavigationInitiationType::USER_INITIATED,
+      web::NavigationManager::UserAgentOverrideOption::INHERIT);
+  [mock_wk_list_ setCurrentURL:@"http://www.url.com/1"
+                  backListURLs:@[ @"http://www.url.com/0" ]
+               forwardListURLs:nil];
+  manager_->CommitPendingItem();
+
+  [mock_wk_list_ moveCurrentToIndex:0];
+  OCMStub([mock_web_view_ URL])
+      .andReturn([NSURL URLWithString:@"http://www.url.com/0"]);
+  manager_->AddPendingItem(
+      GURL("http://www.url.com/0"), Referrer(), ui::PAGE_TRANSITION_TYPED,
+      web::NavigationInitiationType::USER_INITIATED,
+      web::NavigationManager::UserAgentOverrideOption::INHERIT);
+
+  EXPECT_EQ(1, manager_->GetLastCommittedItemIndex());
+  EXPECT_EQ(0, manager_->GetPreviousItemIndex());
+  EXPECT_EQ(0, manager_->GetPendingItemIndex());
+  EXPECT_TRUE(manager_->GetPendingItem() != nullptr);
+
+  // Restores a fake session.
+  std::vector<std::unique_ptr<NavigationItem>> items;
+  items.push_back(base::MakeUnique<NavigationItemImpl>());
+  manager_->Restore(0 /* last_committed_item_index */, std::move(items));
+
+  // Check that last_committed_index, previous_item_index and pending_item_index
+  // are all reset to -1. Note that last_committed_item_index will change to the
+  // value in the restored session (i.e. 0) once restore_session.html finishes
+  // loading in the web view. This is not tested here because this test doesn't
+  // use real WKWebView.
+  EXPECT_EQ(-1, manager_->GetLastCommittedItemIndex());
+  EXPECT_EQ(-1, manager_->GetPreviousItemIndex());
+  EXPECT_EQ(-1, manager_->GetPendingItemIndex());
+
+  // Check that the only pending item is restore_session.html.
+  NavigationItem* pending_item = manager_->GetPendingItem();
+  ASSERT_TRUE(pending_item != nullptr);
+  GURL pending_url = pending_item->GetURL();
+  EXPECT_TRUE(pending_url.SchemeIsFile());
+  EXPECT_EQ("restore_session.html", pending_url.ExtractFileName());
+}
+
 // Tests that Restore() accepts empty session history and performs no-op.
 TEST_F(WKBasedNavigationManagerTest, RestoreSessionWithEmptyHistory) {
   EXPECT_CALL(delegate_, WillLoadCurrentItemWithUrl(testing::_)).Times(0);
diff --git a/ios/web/test/fakes/fake_navigation_manager_delegate.h b/ios/web/test/fakes/fake_navigation_manager_delegate.h
index d4745b9..5716aac 100644
--- a/ios/web/test/fakes/fake_navigation_manager_delegate.h
+++ b/ios/web/test/fakes/fake_navigation_manager_delegate.h
@@ -28,6 +28,7 @@
       const LoadCommittedDetails& load_details) override;
   WebState* GetWebState() override;
   id<CRWWebViewNavigationProxy> GetWebViewNavigationProxy() const override;
+  void RemoveWebView() override;
 
   // Setters for tests to inject dependencies.
   void SetWebViewNavigationProxy(id test_web_view);
diff --git a/ios/web/test/fakes/fake_navigation_manager_delegate.mm b/ios/web/test/fakes/fake_navigation_manager_delegate.mm
index 1c80701d..0932b3dd 100644
--- a/ios/web/test/fakes/fake_navigation_manager_delegate.mm
+++ b/ios/web/test/fakes/fake_navigation_manager_delegate.mm
@@ -32,6 +32,7 @@
 FakeNavigationManagerDelegate::GetWebViewNavigationProxy() const {
   return test_web_view_;
 }
+void FakeNavigationManagerDelegate::RemoveWebView() {}
 
 void FakeNavigationManagerDelegate::SetWebViewNavigationProxy(id web_view) {
   test_web_view_ = web_view;
diff --git a/ios/web/web_state/ui/crw_web_controller.h b/ios/web/web_state/ui/crw_web_controller.h
index 149506c..1fc59f6 100644
--- a/ios/web/web_state/ui/crw_web_controller.h
+++ b/ios/web/web_state/ui/crw_web_controller.h
@@ -118,6 +118,11 @@
 // WebStateImpl API instead of calling this method directly.
 - (void)clearTransientContentView;
 
+// Removes the back WebView. DANGER: this method is exposed for the sole purpose
+// of allowing WKBasedNavigationManagerImpl to reset the back-forward history.
+// Please reconsider before using this method.
+- (void)removeWebView;
+
 // Call to stop the CRWWebController from doing stuff, in particular to
 // stop all network requests. Called as part of the close sequence if it hasn't
 // already been halted; also called from [Tab halt] as part of the shutdown
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index 0d8ff80..4898a23 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -509,8 +509,6 @@
 // Wraps the web view in a CRWWebViewContentView and adds it to the container
 // view.
 - (void)displayWebView;
-// Removes webView.
-- (void)removeWebView;
 // Called when web view process has been terminated.
 - (void)webViewWebProcessDidCrash;
 // Returns the WKWebViewConfigurationProvider associated with the web
diff --git a/ios/web/web_state/web_state_impl.h b/ios/web/web_state/web_state_impl.h
index 3661919e..da10e00a 100644
--- a/ios/web/web_state/web_state_impl.h
+++ b/ios/web/web_state/web_state_impl.h
@@ -291,6 +291,7 @@
 
   WebState* GetWebState() override;
   id<CRWWebViewNavigationProxy> GetWebViewNavigationProxy() const override;
+  void RemoveWebView() override;
 
  protected:
   void AddPolicyDecider(WebStatePolicyDecider* decider) override;
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm
index b5a4ede..178893d 100644
--- a/ios/web/web_state/web_state_impl.mm
+++ b/ios/web/web_state/web_state_impl.mm
@@ -809,6 +809,10 @@
   return [web_controller_ webViewNavigationProxy];
 }
 
+void WebStateImpl::RemoveWebView() {
+  return [web_controller_ removeWebView];
+}
+
 void WebStateImpl::RestoreSessionStorage(CRWSessionStorage* session_storage) {
   SessionStorageBuilder session_storage_builder;
   session_storage_builder.ExtractSessionState(this, session_storage);
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index 246da295..8de633a 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -17,11 +17,11 @@
 crbug.com/707656 editing/undo/undo-indent.html [ Crash Pass ]
 crbug.com/707656 external/wpt/html/editing/editing-0/spelling-and-grammar-checking/spelling-markers-001.html [ Crash Pass ]
 crbug.com/707656 external/wpt/html/editing/focus/processing-model/focus-fixup-rule-one-no-dialogs.html [ Crash Pass ]
-crbug.com/789878 fast/css/first-letter-capitalized-edit-select-crash.html [ Failure ]
+crbug.com/789878 fast/css/first-letter-capitalized-edit-select-crash.html [ Failure Pass ]
 crbug.com/707656 fast/css/readwrite-contenteditable-recalc.html [ Crash Pass ]
-crbug.com/789878 fast/css/readwrite-contenteditable.html [ Failure ]
+crbug.com/789878 fast/css/readwrite-contenteditable.html [ Failure Pass ]
 crbug.com/707656 fast/inline-block/14498-positionForCoordinates.html [ Failure Pass ]
-crbug.com/789878 fast/inline/inline-focus-ring.html [ Failure ]
+crbug.com/789878 fast/inline/inline-focus-ring.html [ Failure Pass ]
 crbug.com/707656 paint/invalidation/remove-anonymous-block-crash.html [ Crash Pass ]
 
 # TextIterator differ in trailing spaces.
@@ -50,7 +50,7 @@
 # Non-interoperable behavior not worth to fix.
 crbug.com/591099 fast/text/apply-start-width-after-skipped-text.html [ Skip ]
 
-crbug.com/714962 intersection-observer/text-target.html [ Failure ]
+crbug.com/714962 intersection-observer/text-target.html [ Failure Pass ]
 
 # New passes
 crbug.com/626703 external/wpt/css/css-ui/text-overflow-021.html [ Failure ]
@@ -126,7 +126,7 @@
 crbug.com/591099 accessibility/textarea-caret-position.html [ Failure Timeout ]
 crbug.com/591099 accessibility/textarea-selection.html [ Failure ]
 crbug.com/591099 accessibility/whitespace-in-name-calc.html [ Failure ]
-crbug.com/591099 animations/animation-ready-reject-script-forbidden.html [ Pass ]
+crbug.com/591099 animations/animation-ready-reject-script-forbidden.html [ Pass Timeout ]
 crbug.com/591099 animations/cross-fade-list-style-image.html [ Failure ]
 crbug.com/591099 animations/interpolation/backdrop-filter-interpolation.html [ Timeout ]
 crbug.com/591099 animations/interpolation/line-height-interpolation.html [ Pass Timeout ]
@@ -1196,7 +1196,7 @@
 crbug.com/591099 css3/masking/clip-path-circle-overflow-hidden.html [ Failure ]
 crbug.com/591099 css3/masking/clip-path-circle-overflow.html [ Failure ]
 crbug.com/591099 css3/masking/clip-path-circle-relative-overflow.html [ Failure ]
-crbug.com/591099 css3/masking/clip-path-circle.html [ Failure ]
+crbug.com/591099 css3/masking/clip-path-circle.html [ Crash Failure ]
 crbug.com/591099 css3/masking/clip-path-ellipse.html [ Failure ]
 crbug.com/591099 css3/masking/clip-path-inset-corners.html [ Failure ]
 crbug.com/591099 css3/masking/clip-path-polygon-evenodd.html [ Failure ]
@@ -1974,16 +1974,16 @@
 crbug.com/591099 editing/assert_selection.html [ Failure ]
 crbug.com/591099 editing/caret/caret-color-001.html [ Failure ]
 crbug.com/591099 editing/caret/caret-color-002.html [ Crash Failure ]
-crbug.com/591099 editing/caret/caret-color-003.html [ Failure ]
+crbug.com/591099 editing/caret/caret-color-003.html [ Crash Failure Timeout ]
 crbug.com/591099 editing/caret/caret-color-004.html [ Crash Failure ]
-crbug.com/591099 editing/caret/caret-color-005.html [ Failure ]
+crbug.com/591099 editing/caret/caret-color-005.html [ Failure Timeout ]
 crbug.com/591099 editing/caret/caret-color-007.html [ Crash Failure ]
 crbug.com/591099 editing/caret/caret-color-010.html [ Crash Failure Timeout ]
 crbug.com/591099 editing/caret/caret-color-011.html [ Failure ]
 crbug.com/591099 editing/caret/caret-color-012.html [ Crash Failure ]
 crbug.com/591099 editing/caret/caret-color-014.html [ Crash Failure ]
 crbug.com/591099 editing/caret/caret-color-015.html [ Crash Failure Timeout ]
-crbug.com/591099 editing/caret/caret-color.html [ Failure ]
+crbug.com/591099 editing/caret/caret-color.html [ Crash Failure ]
 crbug.com/591099 editing/caret/caret-in-empty-cell.html [ Crash Failure Pass Timeout ]
 crbug.com/591099 editing/caret/caret-position.html [ Crash Failure Timeout ]
 crbug.com/591099 editing/deleting/4922367.html [ Failure ]
@@ -2106,7 +2106,7 @@
 crbug.com/591099 editing/pasteboard/5761530-1.html [ Failure ]
 crbug.com/591099 editing/pasteboard/7955.html [ Failure ]
 crbug.com/591099 editing/pasteboard/bad-placeholder.html [ Failure ]
-crbug.com/591099 editing/pasteboard/copy-backslash-with-euc.html [ Crash ]
+crbug.com/591099 editing/pasteboard/copy-backslash-with-euc.html [ Crash Pass ]
 crbug.com/591099 editing/pasteboard/copy-in-password-field.html [ Failure ]
 crbug.com/591099 editing/pasteboard/copy-paste-white-space.html [ Crash ]
 crbug.com/591099 editing/pasteboard/copy-standalone-image.html [ Failure ]
@@ -2164,7 +2164,7 @@
 crbug.com/591099 editing/selection/6476.html [ Failure ]
 crbug.com/591099 editing/selection/caret-and-focus-ring.html [ Failure ]
 crbug.com/591099 editing/selection/caret-at-bidi-boundary.html [ Failure ]
-crbug.com/591099 editing/selection/caret-in-empty-inline-2.html [ Failure ]
+crbug.com/591099 editing/selection/caret-in-empty-inline-2.html [ Failure Pass ]
 crbug.com/591099 editing/selection/caret-ltr-2-left.html [ Failure ]
 crbug.com/591099 editing/selection/caret-ltr-2.html [ Failure ]
 crbug.com/591099 editing/selection/caret-ltr-right.html [ Failure ]
@@ -2410,7 +2410,7 @@
 crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-005.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-006.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-007.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-008.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-008.html [ Crash Failure ]
 crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-009.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-011.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-012.html [ Failure ]
@@ -3811,7 +3811,7 @@
 crbug.com/591099 fast/events/autoscroll-should-not-stop-on-keypress.html [ Failure ]
 crbug.com/591099 fast/events/autoscroll-upwards-propagation-overflow-hidden-iframe-body.html [ Failure ]
 crbug.com/591099 fast/events/autoscroll-with-non-scrollable-parent.html [ Failure ]
-crbug.com/591099 fast/events/autoscroll.html [ Failure ]
+crbug.com/591099 fast/events/autoscroll.html [ Failure Pass ]
 crbug.com/591099 fast/events/change-frame-focus.html [ Failure ]
 crbug.com/591099 fast/events/check-defocus-event-order-when-triggered-by-mouse-click.html [ Failure ]
 crbug.com/591099 fast/events/check-defocus-event-order-when-triggered-by-tab.html [ Failure ]
@@ -4233,7 +4233,7 @@
 crbug.com/591099 fast/forms/textarea/textarea-no-scroll-on-blur.html [ Failure ]
 crbug.com/591099 fast/forms/textarea/textarea-placeholder-visibility-1.html [ Failure ]
 crbug.com/591099 fast/forms/textarea/textarea-placeholder-visibility-2.html [ Failure ]
-crbug.com/591099 fast/forms/textarea/textarea-resize-orthogonal-containing-block.html [ Failure ]
+crbug.com/591099 fast/forms/textarea/textarea-resize-orthogonal-containing-block.html [ Failure Timeout ]
 crbug.com/591099 fast/forms/textarea/textarea-scroll-height.html [ Failure ]
 crbug.com/591099 fast/forms/textarea/textarea-scrollbar.html [ Failure ]
 crbug.com/591099 fast/forms/textarea/textarea-scrolled-focus-ring.html [ Failure ]
@@ -4407,7 +4407,7 @@
 crbug.com/591099 fast/js/same-origin-subframe-about-blank.html [ Failure ]
 crbug.com/591099 fast/js/toString-and-valueOf-override.html [ Failure ]
 crbug.com/591099 fast/js/webidl-type-mapping.html [ Timeout ]
-crbug.com/591099 fast/layers/add-layer-with-nested-stacking.html [ Failure ]
+crbug.com/591099 fast/layers/add-layer-with-nested-stacking.html [ Crash Failure ]
 crbug.com/591099 fast/layers/inline-dirty-z-order-lists.html [ Crash ]
 crbug.com/591099 fast/layers/layer-content-visibility-change.html [ Failure ]
 crbug.com/591099 fast/layers/layer-visibility-sublayer.html [ Failure ]
@@ -4903,6 +4903,7 @@
 crbug.com/591099 fast/overflow/infiniteRecursionGuard.html [ Failure ]
 crbug.com/591099 fast/overflow/line-clamp.html [ Failure ]
 crbug.com/591099 fast/overflow/onscroll-layer-self-destruct.html [ Timeout ]
+crbug.com/591099 fast/overflow/overflow-of-video-outline.html [ Failure ]
 crbug.com/591099 fast/overflow/overflow-rtl-vertical.html [ Failure ]
 crbug.com/591099 fast/overflow/overflow-rtl.html [ Failure ]
 crbug.com/591099 fast/overflow/overflow-update-transform.html [ Failure ]
@@ -4910,7 +4911,6 @@
 crbug.com/591099 fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto.html [ Failure ]
 crbug.com/591099 fast/overflow/scrollbar-restored-and-then-locked.html [ Failure ]
 crbug.com/591099 fast/overflow/scrollbar-restored.html [ Failure ]
-crbug.com/591099 fast/overflow/overflow-of-video-outline.html [ Failure ]
 crbug.com/591099 fast/pagination/auto-height-with-break.html [ Failure ]
 crbug.com/591099 fast/pagination/break-in-paged-overflow.html [ Failure ]
 crbug.com/591099 fast/pagination/caret-range-outside-paged-x-rtl.html [ Failure ]
@@ -4976,9 +4976,15 @@
 crbug.com/591099 external/wpt/css/CSS2/positioning/absolute-replaced-height-001.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-display/display-contents-dynamic-table-002-none.html [ Crash ]
 crbug.com/591099 external/wpt/css/css-display/display-contents-replaced-001.html [ Crash ]
+crbug.com/591099 external/wpt/css/css-display/display-contents-text-inherit.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-flexbox/flexbox_columns-flexitems-2.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-flexbox/flexbox_columns-flexitems.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-flexbox/percentage-heights-003.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-fonts/font-variant-01.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-fonts/font-variant-02.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-fonts/font-variant-03.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-fonts/font-variant-04.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-fonts/matching/fixed-stretch-style-over-weight.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-fonts/test_font_family_parsing.html [ Timeout ]
 crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-non-static-positioned-items-002.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-non-static-positioned-items-005.html [ Failure ]
@@ -4997,6 +5003,116 @@
 crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-positioned-items-with-margin-border-padding-012.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-positioned-items-with-margin-border-padding-015.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-positioned-items-with-margin-border-padding-016.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-001.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-002.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-003.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-004.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-007.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-008.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-br-inside-avoidcolumn-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-break-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-break-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-clip-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-clip-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-collapsing-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-003.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-004.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-005.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-006.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-007.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-invalid-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-invalid-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-toolong-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-containing-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-containing-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-count-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-count-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-count-negative-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-count-negative-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-count-non-integer-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-count-non-integer-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-count-non-integer-003.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-003.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-block-children-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-balance-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-003.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-fraction-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-large-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-large-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-negative-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-height-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-inherit-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-inherit-003.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-list-item-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-margin-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-005.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-003.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-004.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-005.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-overflow-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-overflowing-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-reduce-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-003.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-color-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-color-inherit-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-color-inherit-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-dashed-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-dotted-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-double-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-fraction-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-fraction-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-groove-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-hidden-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-large-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-none-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-percent-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-px-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-ridge-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-samelength-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-shorthand-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-shorthand-2.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-solid-000.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-stacking-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-style-groove-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-style-ridge-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-shorthand-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-000.xht [ Crash ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-001.xht [ Crash ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-002.xht [ Crash ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-003.xht [ Crash ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-block-sibling-003.xht [ Crash ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-child-001.xht [ Crash Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-001.xht [ Crash ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-002.xht [ Crash ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-bottom-001.xht [ Crash ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-001.xht [ Crash ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-002.xht [ Crash ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-003.xht [ Crash ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-firstchild-001.xht [ Crash ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-float-001.xht [ Crash ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-span-none-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-table-cell-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-table-cell-height-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-table-cell-height-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-width-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-width-002.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-width-003.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-width-count-001.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-multicol/multicol-width-count-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-position/position-sticky-nested-inline.html [ Crash ]
 crbug.com/591099 external/wpt/css/css-text-decor/text-emphasis-position-above-left-001.xht [ Crash ]
 crbug.com/591099 external/wpt/css/css-text-decor/text-emphasis-position-above-right-001.xht [ Crash ]
@@ -5160,6 +5276,7 @@
 crbug.com/591099 external/wpt/webrtc/interfaces.https.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/websockets/cookies/005.html [ Pass ]
 crbug.com/591099 external/wpt/websockets/cookies/007.html [ Failure Pass ]
+crbug.com/591099 external/wpt/websockets/opening-handshake/005.html [ Failure Pass ]
 crbug.com/591099 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-wrap_wrapped.html [ Crash ]
 crbug.com/591099 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-wrap_wrapped.html [ Crash ]
 crbug.com/591099 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-wrap_wrapped.html [ Crash ]
@@ -5270,120 +5387,11 @@
 crbug.com/591099 fast/inline/inline-width-containing-collapsed-whitespace-and-image-in-float.html [ Failure ]
 crbug.com/591099 fast/inline/inline-with-empty-inline-children.html [ Failure ]
 crbug.com/591099 fast/lists/list-and-grid.html [ Failure ]
+crbug.com/591099 fast/lists/list-and-margin-collapse.html [ Failure ]
 crbug.com/591099 fast/lists/list-marker-inside-overflow-hidden.html [ Failure ]
 crbug.com/591099 fast/lists/remove-listmarker-from-anonblock-with-continuation-crash.html [ Crash ]
 crbug.com/591099 fast/loader/javascript-url-iframe-crash.html [ Crash ]
 crbug.com/591099 fast/media/mq-display-mode-fullscreen.html [ Crash ]
-crbug.com/591099 external/wpt/css/css-fonts/matching/fixed-stretch-style-over-weight.html [ Pass ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-001.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-002.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-003.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-004.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-007.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-basic-008.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-break-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-clip-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-clip-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-collapsing-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-003.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-004.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-005.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-006.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-007.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-invalid-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-invalid-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-columns-toolong-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-containing-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-containing-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-count-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-count-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-count-negative-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-count-negative-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-count-non-integer-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-count-non-integer-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-count-non-integer-003.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-003.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-auto-block-children-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-fill-balance-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-003.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-fraction-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-large-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-large-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-gap-negative-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-height-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-inherit-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-inherit-003.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-list-item-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-margin-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-005.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-003.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-004.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-nested-margin-005.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-overflow-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-overflowing-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-reduce-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-003.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-color-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-color-inherit-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-color-inherit-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-dashed-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-dotted-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-double-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-fraction-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-fraction-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-groove-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-hidden-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-large-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-none-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-percent-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-px-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-ridge-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-samelength-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-shorthand-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-shorthand-2.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-solid-000.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-stacking-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-style-groove-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-rule-style-ridge-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-shorthand-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-000.xht [ Crash ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-001.xht [ Crash ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-002.xht [ Crash ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-003.xht [ Crash ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-block-sibling-003.xht [ Crash ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-child-001.xht [ Crash ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-001.xht [ Crash ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-002.xht [ Crash ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-bottom-001.xht [ Crash ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-001.xht [ Crash ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-002.xht [ Crash ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-003.xht [ Crash ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-margin-nested-firstchild-001.xht [ Crash ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-float-001.xht [ Crash ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-span-none-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-table-cell-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-table-cell-height-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-table-cell-height-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-width-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-width-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-width-003.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-width-count-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-multicol/multicol-width-count-002.xht [ Failure ]
-crbug.com/591099 external/wpt/websockets/opening-handshake/005.html [ Pass ]
 crbug.com/591099 fast/overflow/overflow-visible-should-ignore-scroll.html [ Failure ]
 crbug.com/591099 fast/pagination/div-x-vertical-lr-ltr.html [ Failure ]
 crbug.com/591099 fast/pagination/div-x-vertical-lr-rtl.html [ Failure ]
@@ -5615,12 +5623,12 @@
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-dynamic-shape.html [ Failure ]
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-edge-case.html [ Failure ]
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-diamond-margin-polygon.html [ Failure ]
-crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-direction-border-box.html [ Failure ]
+crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-direction-border-box.html [ Crash Failure ]
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-direction-content-box.html [ Failure ]
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-direction-padding-box.html [ Failure ]
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-modes-border-box.html [ Failure ]
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-modes-content-box.html [ Failure ]
-crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-modes-padding-box.html [ Failure ]
+crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-modes-padding-box.html [ Crash Failure ]
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-different-writing-modes.html [ Failure ]
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-000.html [ Failure ]
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left.html [ Failure ]
@@ -5670,7 +5678,7 @@
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-relative-size-svg.html [ Failure ]
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-rounded-boxes-001.html [ Failure ]
 crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-rounded-boxes-002.html [ Failure ]
-crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-rounded-inset.html [ Failure ]
+crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-rounded-inset.html [ Crash Failure ]
 crbug.com/591099 fast/spatial-navigation/snav-clipped-overflowed-content.html [ Failure ]
 crbug.com/591099 fast/spatial-navigation/snav-container-white-space.html [ Failure ]
 crbug.com/591099 fast/spatial-navigation/snav-fully-aligned-vertically.html [ Failure ]
@@ -6233,7 +6241,7 @@
 crbug.com/591099 http/tests/devtools/console/shadow-element.js [ Crash Timeout ]
 crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-1.js [ Crash Timeout ]
 crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-2.js [ Pass Timeout ]
-crbug.com/591099 http/tests/devtools/elements/edit/edit-dom-actions-1.js [ Crash Timeout ]
+crbug.com/591099 http/tests/devtools/elements/edit/edit-dom-actions-1.js [ Crash Pass Timeout ]
 crbug.com/591099 http/tests/devtools/elements/edit/edit-dom-actions-4.html [ Timeout ]
 crbug.com/591099 http/tests/devtools/elements/elements-panel-restore-selection-when-node-comes-later.js [ Failure ]
 crbug.com/591099 http/tests/devtools/elements/event-listener-sidebar-jquery1.js [ Failure ]
@@ -6245,7 +6253,6 @@
 crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node-scaled.js [ Failure ]
 crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node-scroll.js [ Failure ]
 crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node.js [ Failure ]
-crbug.com/591099 http/tests/devtools/elements/styles-1/color-aware-property-value-edit.js [ Failure ]
 crbug.com/591099 http/tests/devtools/elements/styles-2/add-import-rule.html [ Failure ]
 crbug.com/591099 http/tests/devtools/elements/styles-3/style-rule-from-imported-stylesheet.html [ Failure ]
 crbug.com/591099 http/tests/devtools/elements/styles-3/styles-add-new-rule-tab.js [ Failure Pass ]
@@ -6258,10 +6265,9 @@
 crbug.com/591099 http/tests/devtools/extensions/extensions-sidebar.html [ Failure ]
 crbug.com/591099 http/tests/devtools/extensions/extensions-timeline-api.html [ Failure ]
 crbug.com/591099 http/tests/devtools/indexeddb/resources-panel.js [ Failure Timeout ]
-crbug.com/591099 http/tests/devtools/network/network-columns-visible.js [ Failure ]
+crbug.com/591099 http/tests/devtools/network/network-columns-visible.js [ Failure Timeout ]
 crbug.com/591099 http/tests/devtools/network/network-datareceived.js [ Failure ]
 crbug.com/591099 http/tests/devtools/network/network-disable-cache-preloads.php [ Failure ]
-crbug.com/591099 http/tests/devtools/network/network-memory-cached-resource.js [ Failure ]
 crbug.com/591099 http/tests/devtools/persistence/automapping-sourcemap-nameclash.js [ Failure ]
 crbug.com/591099 http/tests/devtools/persistence/persistence-tabbed-editor-opens-filesystem-uisourcecode.js [ Failure ]
 crbug.com/591099 http/tests/devtools/runtime/runtime-getProperties.js [ Failure ]
@@ -6925,7 +6931,7 @@
 crbug.com/591099 paint/invalidation/multicol/multicol-with-block.html [ Failure ]
 crbug.com/591099 paint/invalidation/multicol/multicol-with-inline.html [ Failure ]
 crbug.com/591099 paint/invalidation/multicol/multicol-with-overflowing-block-rl.html [ Failure ]
-crbug.com/591099 paint/invalidation/multicol/multicol-with-relpos.html [ Failure ]
+crbug.com/591099 paint/invalidation/multicol/multicol-with-relpos.html [ Crash Failure ]
 crbug.com/591099 paint/invalidation/multicol/multicol-with-text.html [ Failure ]
 crbug.com/591099 paint/invalidation/non-text-link-invalidation-optimization.html [ Failure ]
 crbug.com/591099 paint/invalidation/offset-change-wrong-invalidation-with-float.html [ Failure ]
@@ -7154,7 +7160,7 @@
 crbug.com/591099 paint/invalidation/svg/embedded-svg-size-changes-no-layout-triggers.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/foreign-object-repaint.svg [ Failure ]
 crbug.com/591099 paint/invalidation/svg/nested-embedded-svg-size-changes-no-layout-triggers-1.html [ Failure ]
-crbug.com/591099 paint/invalidation/svg/nested-embedded-svg-size-changes-no-layout-triggers-2.html [ Failure ]
+crbug.com/591099 paint/invalidation/svg/nested-embedded-svg-size-changes-no-layout-triggers-2.html [ Crash Failure ]
 crbug.com/591099 paint/invalidation/svg/nested-embedded-svg-size-changes.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/object-sizing-no-width-height-change-content-box-size.xhtml [ Failure ]
 crbug.com/591099 paint/invalidation/svg/overflow-repaint.html [ Failure ]
@@ -7383,7 +7389,7 @@
 crbug.com/591099 printing/page-break-margin-collapsed.html [ Failure ]
 crbug.com/591099 printing/page-break-orphans-and-widows.html [ Failure ]
 crbug.com/591099 printing/page-break-orphans.html [ Failure ]
-crbug.com/591099 printing/page-break-widows.html [ Failure ]
+crbug.com/591099 printing/page-break-widows.html [ Crash Failure ]
 crbug.com/591099 printing/page-count-relayout-shrink.html [ Failure ]
 crbug.com/591099 printing/quirks-percentage-height-body.html [ Failure ]
 crbug.com/591099 printing/quirks-percentage-height.html [ Failure ]
@@ -7395,7 +7401,7 @@
 crbug.com/591099 printing/subframes-percentage-height.html [ Failure ]
 crbug.com/591099 printing/tfoot-repeats-at-bottom-of-each-page-multiple-tables.html [ Failure ]
 crbug.com/591099 printing/tfoot-repeats-at-bottom-of-each-page.html [ Failure ]
-crbug.com/591099 printing/thead-repeats-at-top-of-each-page-multiple-tables.html [ Failure ]
+crbug.com/591099 printing/thead-repeats-at-top-of-each-page-multiple-tables.html [ Crash Failure ]
 crbug.com/591099 printing/thead-repeats-at-top-of-each-page.html [ Failure ]
 crbug.com/591099 scrollbars/auto-scrollbar-fit-content.html [ Failure ]
 crbug.com/591099 scrollbars/custom-scrollbar-enable-changes-thickness-with-iframe.html [ Failure ]
@@ -7602,7 +7608,7 @@
 crbug.com/591099 svg/custom/inline-svg-use-available-width-in-stf.html [ Failure ]
 crbug.com/591099 svg/custom/invisible-text-after-scrolling.xhtml [ Failure ]
 crbug.com/591099 svg/custom/junk-data.svg [ Failure ]
-crbug.com/591099 svg/custom/load-non-wellformed.svg [ Failure ]
+crbug.com/591099 svg/custom/load-non-wellformed.svg [ Crash Failure ]
 crbug.com/591099 svg/custom/marker-orient-auto.html [ Failure ]
 crbug.com/591099 svg/custom/missing-xlink.svg [ Failure ]
 crbug.com/591099 svg/custom/mouse-move-on-svg-container.xhtml [ Timeout ]
@@ -7654,7 +7660,7 @@
 crbug.com/591099 svg/dynamic-updates/SVGAElement-svgdom-target-prop.html [ Failure ]
 crbug.com/591099 svg/dynamic-updates/SVGClipPath-influences-hitTesting.html [ Failure ]
 crbug.com/591099 svg/dynamic-updates/SVGClipPathElement-css-transform-influences-hitTesting.html [ Failure ]
-crbug.com/591099 svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting.html [ Failure ]
+crbug.com/591099 svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting.html [ Crash Failure ]
 crbug.com/591099 svg/filters/feBlend-all-modes.html [ Failure ]
 crbug.com/591099 svg/filters/feTurbulence-bad-seeds.html [ Crash Failure ]
 crbug.com/591099 svg/foreign-object-under-shadow-root-under-hidden.html [ Failure ]
@@ -7668,7 +7674,7 @@
 crbug.com/591099 svg/foreignObject/no-crash-with-svg-content-in-html-document.svg [ Failure ]
 crbug.com/591099 svg/foreignObject/svg-document-in-html-document.svg [ Failure ]
 crbug.com/591099 svg/hittest/clip-path-shape.html [ Failure ]
-crbug.com/591099 svg/hittest/ellipse-hittest.html [ Failure ]
+crbug.com/591099 svg/hittest/ellipse-hittest.html [ Crash Failure ]
 crbug.com/591099 svg/hittest/empty-container.html [ Failure ]
 crbug.com/591099 svg/hittest/pointer-events-all.html [ Failure ]
 crbug.com/591099 svg/hittest/pointer-events-all2.html [ Failure ]
@@ -7708,7 +7714,7 @@
 crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-auto.xhtml [ Failure ]
 crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-defaults.xhtml [ Failure ]
 crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-hidden.xhtml [ Failure ]
-crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-scroll.xhtml [ Failure ]
+crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-scroll.xhtml [ Crash Failure ]
 crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-visible.xhtml [ Failure ]
 crbug.com/591099 svg/parser/whitespace-length-invalid-1.html [ Pass Timeout ]
 crbug.com/591099 svg/parser/whitespace-length-invalid-2.html [ Pass Timeout ]
@@ -7830,7 +7836,7 @@
 crbug.com/591099 tables/mozilla/bugs/bug88524.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug98196.html [ Failure ]
 crbug.com/591099 tables/mozilla/collapsing_borders/bug41262-3.html [ Failure ]
-crbug.com/591099 tables/mozilla/core/bloomberg.html [ Failure ]
+crbug.com/591099 tables/mozilla/core/bloomberg.html [ Crash Failure ]
 crbug.com/591099 tables/mozilla/core/captions.html [ Failure ]
 crbug.com/591099 tables/mozilla/core/cell_heights.html [ Failure ]
 crbug.com/591099 tables/mozilla/core/table_heights.html [ Failure ]
@@ -7948,7 +7954,7 @@
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-border-image-source.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-border-radius.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-drag-image.html [ Failure ]
-crbug.com/591099 virtual/gpu-rasterization/images/color-profile-filter.html [ Failure ]
+crbug.com/591099 virtual/gpu-rasterization/images/color-profile-filter.html [ Failure Timeout ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-group.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-iframe.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ Failure ]
@@ -8025,7 +8031,7 @@
 crbug.com/591099 virtual/gpu-rasterization/images/webp-flip.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/width-on-broken-data-src.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/zoomed-img-size.html [ Crash ]
-crbug.com/591099 virtual/gpu/fast/canvas/OffscreenCanvas-2d-imageSmoothing.html [ Pass ]
+crbug.com/591099 virtual/gpu/fast/canvas/OffscreenCanvas-2d-imageSmoothing.html [ Pass Timeout ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-createImageBitmap-colorClamping.html [ Pass ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-createImageBitmap-drawImage.html [ Timeout ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-drawImage-animated-images.html [ Failure ]
@@ -8034,19 +8040,38 @@
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-imageSmoothingQuality.html [ Pass ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-measure-bidi-text.html [ Failure ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-render-layer.html [ Failure ]
-crbug.com/591099 virtual/gpu/fast/canvas/canvas-shadow-source-in.html [ Failure ]
+crbug.com/591099 virtual/gpu/fast/canvas/canvas-shadow-source-in.html [ Crash Failure Timeout ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-transforms-during-path.html [ Failure ]
 crbug.com/591099 virtual/gpu/fast/canvas/fill-stroke-clip-reset-path.html [ Failure ]
 crbug.com/591099 virtual/gpu/fast/canvas/fillrect_gradient.html [ Failure ]
 crbug.com/591099 virtual/gpu/fast/canvas/patternfill-repeat.html [ Failure Timeout ]
 crbug.com/591099 virtual/high-contrast-mode/paint/high-contrast-mode/image-filter-all/text-on-backgrounds.html [ Failure ]
+crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/MouseEvent-prototype-offsetX-offsetY.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-001.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/untriaged/shadow-trees/shadow-root-002.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/external/wpt/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-002.html [ Pass ]
 crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/focus-navigation-with-distributed-nodes.html [ Crash ]
 crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/form-in-shadow.html [ Crash ]
 crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/selection-in-nested-shadow.html [ Failure ]
 crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/selections-in-shadow.html [ Timeout ]
 crbug.com/591099 virtual/incremental-shadow-dom/fast/dom/shadow/shadow-dom-event-dispatching-svg-in-shadow-subtree.html [ Failure ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/active-element.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/css-cascade-outer-scope2.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/css-cascade-slot-distributed.html [ Pass ]
 crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/event-composed-ua.html [ Timeout ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/focus-navigation-slot-nested-delegatesFocus.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/focus-navigation-slot-nested.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/focus-navigation-slot-with-tabindex.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/focus-navigation-slots.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/focus-navigation.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/host-pseudo-elements.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/layout.html [ Pass ]
 crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/range-caret-range-from-point-left-of-shadow.html [ Crash ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/slots-1.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/slots-2.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/slots-dynamic.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/slotted-pseudo-element-shared-style.html [ Pass ]
+crbug.com/591099 virtual/incremental-shadow-dom/shadow-dom/slotted-pseudo-element.html [ Pass ]
 crbug.com/591099 virtual/layout_ng/ [ Skip ]
 crbug.com/591099 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/float-replaced-width-002.xht [ Pass ]
 crbug.com/591099 virtual/layout_ng/external/wpt/css/CSS2/positioning/position-static-001.xht [ Pass ]
@@ -8061,8 +8086,8 @@
 crbug.com/591099 virtual/layout_ng/fast/block/margin-collapse/self-collapsing-cols-creates-block-formatting-context.html [ Pass ]
 crbug.com/591099 virtual/layout_ng/overflow/overflow-basic-003.html [ Pass ]
 crbug.com/591099 virtual/layout_ng/overflow/overflow-bug-chrome-ng-001.html [ Pass ]
+crbug.com/714962 virtual/layout_ng_paint/fast/inline/drawStyledEmptyInlinesWithWS.html [ Failure Pass ]
 crbug.com/591099 virtual/layout_ng_paint/fast/inline/inline-box-adjust-position-crash.html [ Pass ]
-crbug.com/714962 virtual/layout_ng_paint/fast/inline/drawStyledEmptyInlinesWithWS.html [ Failure ]
 crbug.com/591099 virtual/mojo-blobs/ [ Skip ]
 crbug.com/591099 virtual/mojo-localstorage/ [ Skip ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/anchor-empty-focus.html [ Failure ]
@@ -8072,7 +8097,7 @@
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-should-not-stop-on-keypress.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-upwards-propagation-overflow-hidden-iframe-body.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-with-non-scrollable-parent.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll.html [ Failure Pass ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/change-frame-focus.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/check-defocus-event-order-when-triggered-by-mouse-click.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/check-defocus-event-order-when-triggered-by-tab.html [ Failure ]
@@ -8124,7 +8149,7 @@
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/mousemove-to-resizer-changes-cursor.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouseover-mouseout.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/no-blur-on-enter-button.html [ Failure ]
-crbug.com/591099 virtual/mouseevent_fractional/fast/events/offsetX-offsetY.html [ Failure ]
+crbug.com/591099 virtual/mouseevent_fractional/fast/events/offsetX-offsetY.html [ Failure Pass ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/onblur-remove.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/onchange-range-slider.html [ Crash ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/onclick-list-marker.html [ Failure ]
@@ -8357,8 +8382,14 @@
 crbug.com/591099 virtual/spv175/compositing/layers-inside-overflow-scroll.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/lots-of-img-layers-with-opacity.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/lots-of-img-layers.html [ Failure ]
+crbug.com/591099 virtual/spv175/compositing/masks/direct-image-mask.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/masks/mask-layer-size.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/masks/mask-of-clipped-layer.html [ Failure ]
+crbug.com/591099 virtual/spv175/compositing/masks/mask-with-added-filters.html [ Failure ]
+crbug.com/591099 virtual/spv175/compositing/masks/mask-with-removed-filters.html [ Failure ]
+crbug.com/591099 virtual/spv175/compositing/masks/masked-ancestor.html [ Failure ]
+crbug.com/591099 virtual/spv175/compositing/masks/multiple-masks.html [ Failure ]
+crbug.com/591099 virtual/spv175/compositing/masks/simple-composited-mask.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/nested-border-radius-composited-child.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/accelerated-overflow-scroll-should-not-affect-perspective.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/ancestor-overflow.html [ Failure ]
@@ -8375,6 +8406,7 @@
 crbug.com/591099 virtual/spv175/compositing/overflow/fractional-sized-scrolling-layer.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/get-transform-from-non-box-container.html [ Crash ]
 crbug.com/591099 virtual/spv175/compositing/overflow/mask-with-filter.html [ Failure ]
+crbug.com/591099 virtual/spv175/compositing/overflow/mask-with-small-content-rect.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/nested-border-radius-clipping.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/nested-render-surfaces-with-intervening-clip.html [ Failure ]
 crbug.com/591099 virtual/spv175/compositing/overflow/nested-render-surfaces-with-rotation.html [ Failure ]
@@ -8786,7 +8818,7 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/multicol/multicol-with-abspos.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/multicol/multicol-with-block.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/multicol/multicol-with-inline.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/multicol/multicol-with-relpos.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/multicol/multicol-with-relpos.html [ Crash Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/multicol/multicol-with-text.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/non-text-link-invalidation-optimization.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/outline/border-outline-0.html [ Failure ]
@@ -8826,6 +8858,7 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/clipped-overflow-visible-subtree.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/composited-overflow-with-borderbox-background.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/composited-overflow-with-local-background.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/overflow/composited-overflow-with-negative-offset-outline.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/composited-vertical-rl-overflow.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/content-into-overflow.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/overflow/erase-overflow.html [ Failure ]
@@ -9013,7 +9046,7 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-content.xhtml [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-deep-shadow-tree-content.xhtml [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-image.xhtml [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-inner-svg.xhtml [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-inner-svg.xhtml [ Crash Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-shadow-tree-content-with-symbol.xhtml [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-shadow-tree-content.xhtml [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/relative-sized-use-on-symbol.xhtml [ Crash Failure ]
@@ -9024,7 +9057,7 @@
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/repaint-svg-after-style-change.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/resize-svg-invalidate-children-2.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/resize-svg-invalidate-children.html [ Failure ]
-crbug.com/591099 virtual/spv175/paint/invalidation/svg/scroll-hit-test.xhtml [ Failure ]
+crbug.com/591099 virtual/spv175/paint/invalidation/svg/scroll-hit-test.xhtml [ Crash Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/svg-background-partial-redraw.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/invalidation/svg/svg-image-change-content-size.xhtml [ Failure ]
@@ -9151,6 +9184,7 @@
 crbug.com/591099 virtual/spv175/paint/markers/marker-early-break-bug.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/markers/suggestion-marker-basic.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/markers/suggestion-marker-split.html [ Failure ]
+crbug.com/591099 virtual/spv175/paint/masks/fieldset-mask.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/overflow/composited-rounded-clip-floating-element.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/overflow/fixed-background-scroll-window.html [ Failure ]
 crbug.com/591099 virtual/spv175/paint/overflow/non-composited-fixed-position-descendant.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 02fd350..62a7271 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -3052,15 +3052,7 @@
 
 # crbug.com/736177: Failures likely related to different results on Mac with different GPUs
 crbug.com/736177 [ Mac10.12 ] fast/forms/form-element-geometry.html [ Failure Pass ]
-# These tests are failing on both Mac-10.12 when using an Intel GPU and Mac-10.11.6 when using no GPU
-crbug.com/736177 [ Mac ] fast/forms/control-restrict-line-height.html [ Failure Pass ]
 crbug.com/736177 [ Mac ] fast/forms/input-appearance-height.html [ Failure Pass ]
-crbug.com/736177 [ Mac ] fast/forms/placeholder-position.html [ Failure Pass ]
-crbug.com/736177 [ Mac ] fast/forms/search/search-appearance-basic.html [ Failure Pass ]
-crbug.com/736177 [ Mac ] fast/forms/search/search-cancel-button-style-sharing.html [ Failure Pass ]
-crbug.com/736177 [ Mac ] fast/forms/search/search-display-none-cancel-button.html [ Failure Pass ]
-crbug.com/736177 [ Mac ] fast/forms/search/search-rtl.html [ Failure Pass ]
-crbug.com/736177 [ Mac ] fast/forms/search/searchfield-heights.html [ Failure Pass ]
 # These tests are failing on Mac-10.12 when using an Intel GPU and Mac Retina
 crbug.com/736177 [ Mac10.12 Retina ] compositing/overflow/theme-affects-visual-overflow.html [ Failure Pass ]
 crbug.com/736177 [ Mac10.12 Retina ] css1/box_properties/acid_test.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/fast/dom/resources/script-element-gc.js b/third_party/WebKit/LayoutTests/fast/dom/resources/script-element-gc.js
index 5ee1e8a0..6f05b42 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/resources/script-element-gc.js
+++ b/third_party/WebKit/LayoutTests/fast/dom/resources/script-element-gc.js
@@ -1,13 +1,3 @@
-function gc()
-{
-    if (window.GCController)
-        return GCController.collectAll();
-
-    for (var i = 0; i < 10000; i++) { // > force garbage collection (FF requires about 9K allocations before a collect)
-        var s = new String("");
-    }
-}
-
 function removeScriptElement() {
     var s = document.getElementById('theScript');
     s.parentNode.removeChild(s);
diff --git a/third_party/WebKit/LayoutTests/fast/events/destroyed-atomic-string.html-disabled b/third_party/WebKit/LayoutTests/fast/events/destroyed-atomic-string.html-disabled
index 5ed0f0ea..e012d99 100644
--- a/third_party/WebKit/LayoutTests/fast/events/destroyed-atomic-string.html-disabled
+++ b/third_party/WebKit/LayoutTests/fast/events/destroyed-atomic-string.html-disabled
@@ -1,18 +1,8 @@
 <body>
 <p>Test that adding an event listener for an event with a unique name works correctly (this used to corrupt event listener map after GC).</p>
 <pre id=log></pre>
-
+<script src="../../resources/gc.js"></script>
 <script>
-function gc()
-{
-    if (window.GCController)
-        return GCController.collect();
-
-    for (var i = 0; i < 10000; i++) { // > force garbage collection (FF requires about 9K allocations before a collect)
-        var s = new String("abc");
-    }
-}
-
 function log(message)
 {
     document.getElementById("log").innerHTML += message + "<br>";
diff --git a/third_party/WebKit/LayoutTests/fast/events/nested-event-remove-node-crash.html b/third_party/WebKit/LayoutTests/fast/events/nested-event-remove-node-crash.html
index b1b8a06..3c1e2c2 100644
--- a/third_party/WebKit/LayoutTests/fast/events/nested-event-remove-node-crash.html
+++ b/third_party/WebKit/LayoutTests/fast/events/nested-event-remove-node-crash.html
@@ -1,5 +1,6 @@
 <html>
 <head>
+<script src="../../resources/gc.js"></script>
 <script>
 function sendXHR()
 {
@@ -43,18 +44,6 @@
     }
 }
 
-function GC()
-{
-    // Force GC.
-    if (window.GCController)
-        GCController.collect();
-    else {
-        for (var i = 0; i < 10000; ++i) {
-            ({ });
-        }
-    }
-}
-
 /* GLOBALS */
 var XHR = new Array();
 var numXHRs = 0;
@@ -67,7 +56,7 @@
 <div id="replaceMe">
 
 <div>
-<select id="theSelect" onblur="sendXHR();GC();">
+<select id="theSelect" onblur="sendXHR();gc();">
 </select>
 </div>
 
diff --git a/third_party/WebKit/LayoutTests/fast/events/script-tests/event-listener-sharing.js b/third_party/WebKit/LayoutTests/fast/events/script-tests/event-listener-sharing.js
index dbfd9f16..d1b4844 100644
--- a/third_party/WebKit/LayoutTests/fast/events/script-tests/event-listener-sharing.js
+++ b/third_party/WebKit/LayoutTests/fast/events/script-tests/event-listener-sharing.js
@@ -2,15 +2,6 @@
 "Tests that an event handler registered on two nodes still fires after one of the nodes has been GC'd."
 );
 
-function gc() {
-    if (window.GCController)
-        GCController.collect();
-    else {
-        for (var i = 0; i < 10000; ++i)
-            new Object;
-    }
-}
-
 var clickCount = 0;
 function clickHandler() {
     ++clickCount;
diff --git a/third_party/WebKit/LayoutTests/fast/js/mozilla/resources/moz-test-pre.js b/third_party/WebKit/LayoutTests/fast/js/mozilla/resources/moz-test-pre.js
index 8564dec..10fa556 100644
--- a/third_party/WebKit/LayoutTests/fast/js/mozilla/resources/moz-test-pre.js
+++ b/third_party/WebKit/LayoutTests/fast/js/mozilla/resources/moz-test-pre.js
@@ -281,22 +281,6 @@
     testFailed(_a + " should throw an instance of " + _e.name);
 }
 
-function gc() {
-    if (typeof GCController !== "undefined")
-        GCController.collect();
-    else {
-        function gcRec(n) {
-            if (n < 1)
-                return {};
-            var temp = {i: "ab" + i + (i / 100000)};
-            temp += "foo";
-            gcRec(n-1);
-        }
-        for (var i = 0; i < 1000; i++)
-            gcRec(10)
-    }
-}
-
 // It's possible for an async test to call finishJSTest() before moz-test-post.js
 // has been parsed.
 function finishJSTest()
@@ -324,4 +308,4 @@
         testFailed(message);
     else
         testFailed("assertEq failed: " + left + "(of type " + (typeof left) + ") !== " + right + "(of type " + (typeof right) + ")");
-}
\ No newline at end of file
+}
diff --git a/third_party/WebKit/LayoutTests/fast/js/script-tests/cached-eval-gc.js b/third_party/WebKit/LayoutTests/fast/js/script-tests/cached-eval-gc.js
index 0a8d555..806a8d90 100644
--- a/third_party/WebKit/LayoutTests/fast/js/script-tests/cached-eval-gc.js
+++ b/third_party/WebKit/LayoutTests/fast/js/script-tests/cached-eval-gc.js
@@ -2,15 +2,6 @@
 'Tests to make sure we do not gc the constants contained by functions defined inside eval code.  To pass we need to not crash.'
 );
 
-function gc()
-{
-    if (this.GCController)
-        GCController.collect();
-    else
-        for (var i = 0; i < 10000; ++i) // Allocate a sufficient number of objects to force a GC.
-            ({});
-}
-
 evalStringTest = "'test'";
 evalString = "function f() { shouldBe(\"'test'\", evalStringTest) }; f()";
 function doTest() {
diff --git a/third_party/WebKit/LayoutTests/fast/js/script-tests/with-scope-gc.js b/third_party/WebKit/LayoutTests/fast/js/script-tests/with-scope-gc.js
index a661de8e..6f87d138 100644
--- a/third_party/WebKit/LayoutTests/fast/js/script-tests/with-scope-gc.js
+++ b/third_party/WebKit/LayoutTests/fast/js/script-tests/with-scope-gc.js
@@ -2,15 +2,6 @@
 'Tests to make sure that dynamic scope objects are correctly protected from GC.  To pass we need to not crash.'
 );
 
-function gc()
-{
-    if (this.GCController)
-        GCController.collectAll();
-    else
-        for (var i = 0; i < 10000; ++i) // Allocate a sufficient number of objects to force a GC.
-            ({});
-}
-
 (function() {
     try {
         // Immediate value for scope
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/worklet-should-report-context-destroyed.html b/third_party/WebKit/LayoutTests/http/tests/worklet/worklet-should-report-context-destroyed.html
index 09d236d2..28543199 100644
--- a/third_party/WebKit/LayoutTests/http/tests/worklet/worklet-should-report-context-destroyed.html
+++ b/third_party/WebKit/LayoutTests/http/tests/worklet/worklet-should-report-context-destroyed.html
@@ -3,6 +3,7 @@
 <html>
 <title>Worklet: Worklet should report context destroyed</title>
 <body>
+<script src="../../../resources/gc.js"></script>
 <script>
 // This test was added for confirming a crash bug fix (see
 // https://crbug.com/657450). This should not be upstreamed to WPT because of
@@ -12,16 +13,6 @@
   testRunner.dumpAsText();
 }
 
-function gc()
-{
-  if (window.GCController) {
-    GCController.collect();
-  } else {
-    for (var i = 0; i < 10000; ++i)
-      new Object;
-  }
-}
-
 function tryCrash()
 {
   document.frame.CSS.paintWorklet;
diff --git a/third_party/WebKit/LayoutTests/media/track/text-track-cue-exceptions-expected.txt b/third_party/WebKit/LayoutTests/media/track/text-track-cue-exceptions-expected.txt
deleted file mode 100644
index d25ac94..0000000
--- a/third_party/WebKit/LayoutTests/media/track/text-track-cue-exceptions-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-Verify that TextTrackCue exceptions are properly messaged to developers.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS cue.startTime = Number.NaN; threw exception TypeError: Failed to set the 'startTime' property on 'TextTrackCue': The provided double value is non-finite..
-PASS cue.startTime = Number.POSITIVE_INFINITY; threw exception TypeError: Failed to set the 'startTime' property on 'TextTrackCue': The provided double value is non-finite..
-PASS cue.startTime = Number.NEGATIVE_INFINITY; threw exception TypeError: Failed to set the 'startTime' property on 'TextTrackCue': The provided double value is non-finite..
-PASS cue.endTime = Number.NaN; threw exception TypeError: Failed to set the 'endTime' property on 'TextTrackCue': The provided double value is non-finite..
-PASS cue.endTime = Number.POSITIVE_INFINITY; threw exception TypeError: Failed to set the 'endTime' property on 'TextTrackCue': The provided double value is non-finite..
-PASS cue.endTime = Number.NEGATIVE_INFINITY; threw exception TypeError: Failed to set the 'endTime' property on 'TextTrackCue': The provided double value is non-finite..
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/media/track/text-track-cue-exceptions.html b/third_party/WebKit/LayoutTests/media/track/text-track-cue-exceptions.html
index 9f687da..621b8fb 100644
--- a/third_party/WebKit/LayoutTests/media/track/text-track-cue-exceptions.html
+++ b/third_party/WebKit/LayoutTests/media/track/text-track-cue-exceptions.html
@@ -1,17 +1,28 @@
 <!DOCTYPE html>
-<script src="../../resources/js-test.js"></script>
-<body>
+<title>TextTrackCue exceptions are properly messaged to developers</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
 <script>
-description("Verify that TextTrackCue exceptions are properly messaged to developers.");
-
-var cue = new VTTCue(0, 0, "Test.");
-
-function testInfinityAndNaN(property) {
-    shouldThrow("cue." + property + " = Number.NaN;");
-    shouldThrow("cue." + property + " = Number.POSITIVE_INFINITY;");
-    shouldThrow("cue." + property + " = Number.NEGATIVE_INFINITY;");
+function getExceptionMsg(property) {
+    return "Failed to set the '" + property
+        + "' property on 'TextTrackCue': The provided double value is non-finite.";
 }
-
-testInfinityAndNaN("startTime");
-testInfinityAndNaN("endTime");
+var cue = new VTTCue(0, 0, "Test.");
+function testProperty(property) {
+    var expected_exception_msg = getExceptionMsg(property);
+    test(function() {
+        var testValues = [Number.NaN, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY];
+        testValues.forEach(function(value) {
+            try {
+                cue[property] = value;
+                assert_unreached("should throw");
+            } catch (e) {
+                assert_equals(e.name, "TypeError");
+                assert_equals(e.message, expected_exception_msg);
+            }
+        });
+    }, expected_exception_msg);
+}
+testProperty("startTime");
+testProperty("endTime");
 </script>
diff --git a/third_party/WebKit/LayoutTests/media/track/track-node-add-remove-expected.txt b/third_party/WebKit/LayoutTests/media/track/track-node-add-remove-expected.txt
deleted file mode 100644
index 7f1c130..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-node-add-remove-expected.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Adding tracks outside the DOM tree:
-PASS video.textTracks.length is 2
-PASS video.textTracks[0] is tracka.track
-PASS video.textTracks[1] is trackb.track
-Inserting the parent video element into the document.
-PASS video.textTracks.length is 2
-PASS video.textTracks[0] is tracka.track
-PASS video.textTracks[1] is trackb.track
-Inserting and removing another track in the document.
-PASS video.textTracks.length is 3
-PASS video.textTracks[2] is trackc.track
-PASS video.textTracks.length is 2
-PASS video.textTracks[0] is tracka.track
-PASS video.textTracks[1] is trackc.track
-Removing the video from the document.
-PASS video.textTracks.length is 2
-PASS video.textTracks[0] is tracka.track
-PASS video.textTracks[1] is trackc.track
-PASS video.textTracks.length is 1
-PASS video.textTracks[0] is trackc.track
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/media/track/track-node-add-remove.html b/third_party/WebKit/LayoutTests/media/track/track-node-add-remove.html
index 78b19cf..177d083 100644
--- a/third_party/WebKit/LayoutTests/media/track/track-node-add-remove.html
+++ b/third_party/WebKit/LayoutTests/media/track/track-node-add-remove.html
@@ -1,49 +1,36 @@
 <!DOCTYPE html>
-<html>
-<head>
-<script src="../../resources/js-test.js"></script>
-</head>
+<title>Adding and removing track node</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
 <body>
 <script>
-var video = document.createElement('video');
+test(function() {
+  var video = document.createElement('video');
+  var tracka = document.createElement('track');
+  video.appendChild(tracka);
+  var trackb = document.createElement('track');
+  video.appendChild(trackb);
 
-var tracka = document.createElement('track');
-video.appendChild(tracka);
-var trackb = document.createElement('track');
-video.appendChild(trackb);
+  // Adding tracks outside the DOM tree.
+  assert_array_equals(video.textTracks, [tracka.track, trackb.track]);
 
-debug("Adding tracks outside the DOM tree:");
-shouldBe("video.textTracks.length", "2");
-shouldBe("video.textTracks[0]", "tracka.track");
-shouldBe("video.textTracks[1]", "trackb.track");
+  // Inserting the parent video element into the document.
+  document.body.appendChild(video);
+  assert_array_equals(video.textTracks, [tracka.track, trackb.track]);
 
-debug("Inserting the parent video element into the document.");
-document.body.appendChild(video);
-shouldBe("video.textTracks.length", "2");
-shouldBe("video.textTracks[0]", "tracka.track");
-shouldBe("video.textTracks[1]", "trackb.track");
+  // Inserting and removing another track in the document.
+  var trackc = document.createElement('track');
+  video.appendChild(trackc);
+  assert_array_equals(video.textTracks, [tracka.track, trackb.track, trackc.track]);
 
-debug("Inserting and removing another track in the document.");
-var trackc = document.createElement('track');
-video.appendChild(trackc);
-shouldBe("video.textTracks.length", "3");
-shouldBe("video.textTracks[2]", "trackc.track");
+  trackb.parentNode.removeChild(trackb);
+  assert_array_equals(video.textTracks, [tracka.track, trackc.track]);
 
-trackb.parentNode.removeChild(trackb);
-shouldBe("video.textTracks.length", "2");
-shouldBe("video.textTracks[0]", "tracka.track");
-shouldBe("video.textTracks[1]", "trackc.track");
+  // Removing the video from the document.
+  document.body.removeChild(video);
+  assert_array_equals(video.textTracks, [tracka.track, trackc.track]);
 
-debug("Removing the video from the document.");
-document.body.removeChild(video);
-shouldBe("video.textTracks.length", "2");
-shouldBe("video.textTracks[0]", "tracka.track");
-shouldBe("video.textTracks[1]", "trackc.track");
-
-tracka.parentNode.removeChild(tracka);
-shouldBe("video.textTracks.length", "1");
-shouldBe("video.textTracks[0]", "trackc.track");
-
+  tracka.parentNode.removeChild(tracka);
+  assert_array_equals(video.textTracks, [trackc.track]);
+});
 </script>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/media/track/vtt-cue-exceptions-expected.txt b/third_party/WebKit/LayoutTests/media/track/vtt-cue-exceptions-expected.txt
deleted file mode 100644
index bf9f891a..0000000
--- a/third_party/WebKit/LayoutTests/media/track/vtt-cue-exceptions-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-Verify that VTTCue exceptions are properly messaged to developers.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS cue.position = -1; threw exception IndexSizeError: Failed to set the 'position' property on 'VTTCue': The value provided (-1) is outside the range [0, 100]..
-PASS cue.position = 101; threw exception IndexSizeError: Failed to set the 'position' property on 'VTTCue': The value provided (101) is outside the range [0, 100]..
-PASS cue.size = -1; threw exception IndexSizeError: Failed to set the 'size' property on 'VTTCue': The value provided (-1) is outside the range [0, 100]..
-PASS cue.size = 101; threw exception IndexSizeError: Failed to set the 'size' property on 'VTTCue': The value provided (101) is outside the range [0, 100]..
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/media/track/vtt-cue-exceptions.html b/third_party/WebKit/LayoutTests/media/track/vtt-cue-exceptions.html
index 250beff2..d9bcd73 100644
--- a/third_party/WebKit/LayoutTests/media/track/vtt-cue-exceptions.html
+++ b/third_party/WebKit/LayoutTests/media/track/vtt-cue-exceptions.html
@@ -1,21 +1,28 @@
 <!DOCTYPE html>
-<html>
-<head>
-    <script src="../../resources/js-test.js"></script>
-</head>
-<body>
-    <script>
-        description("Verify that VTTCue exceptions are properly messaged to developers.");
-
-        var cue = new VTTCue(0, 0, "Test.");
-
-        function testPercentage(property) {
-            shouldThrow("cue." + property + " = -1;");
-            shouldThrow("cue." + property + " = 101;");
+<title>VTTCue exceptions are properly messaged to developers</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+function getExceptionMsg(property, value) {
+    return "Failed to set the '" + property
+        + "' property on 'VTTCue': The value provided ("
+        + value + ") is outside the range [0, 100].";
+}
+var cue = new VTTCue(0, 0, "Test.");
+function testProperty(property, value) {
+    var expected_exception_msg = getExceptionMsg(property, value);
+    test(function() {
+        try {
+            cue[property] = value;
+            assert_unreached("should throw");
+        } catch (e) {
+            assert_equals(e.name, "IndexSizeError");
+            assert_equals(e.message, expected_exception_msg);
         }
-
-        testPercentage("position");
-        testPercentage("size");
-    </script>
-</body>
-</html>
+    }, expected_exception_msg);
+}
+testProperty("position", -1);
+testProperty("position", 101);
+testProperty("size", -1);
+testProperty("size", 101);
+</script>
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/input-appearance-height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/input-appearance-height-expected.png
index c3e43642..a02800c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/input-appearance-height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/input-appearance-height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.png
index aee0d16..5250014 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/placeholder-position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-appearance-basic-expected.png
index e27915f..9fa610af 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-cancel-button-style-sharing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-cancel-button-style-sharing-expected.png
index f9c63c62..9021df3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-cancel-button-style-sharing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-cancel-button-style-sharing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-rtl-expected.png
index b0c96eda..1cc9b4c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-rtl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-rtl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/input-appearance-height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/input-appearance-height-expected.png
index 1612592..588a6d0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/input-appearance-height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/input-appearance-height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/placeholder-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/placeholder-position-expected.png
index 68da93f71..4755d06 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/placeholder-position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/placeholder-position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-appearance-basic-expected.png
index acf9689..0e30d3f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-cancel-button-style-sharing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-cancel-button-style-sharing-expected.png
index 37620a2..db2c8ee 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-cancel-button-style-sharing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-cancel-button-style-sharing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.png
index 40ca375..e11f5c8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.txt
new file mode 100644
index 0000000..16f973e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-rtl-expected.txt
@@ -0,0 +1,62 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x576
+      LayoutBlockFlow {P} at (0,0) size 784x18
+        LayoutText {#text} at (0,0) size 54x18
+          text run at (0,0) width 54: "Test for "
+        LayoutInline {I} at (0,0) size 702x18
+          LayoutInline {A} at (0,0) size 304x18 [color=#0000EE]
+            LayoutText {#text} at (53,0) size 304x18
+              text run at (53,0) width 304: "http://bugs.webkit.org/show_bug.cgi?id=11916"
+          LayoutText {#text} at (356,0) size 399x18
+            text run at (356,0) width 5: " "
+            text run at (360,0) width 395: "REGRESSION (SearchField): RTL search fields are mixed up"
+        LayoutText {#text} at (754,0) size 5x18
+          text run at (754,0) width 5: "."
+      LayoutBlockFlow {P} at (0,34) size 784x57
+        LayoutTextControl {INPUT} at (0,0) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+          LayoutFlexibleBox {DIV} at (4,3) size 125x13
+            LayoutBlockFlow {DIV} at (12,0) size 113x13
+        LayoutText {#text} at (133,0) size 4x18
+          text run at (133,0) width 4: " "
+        LayoutBR {BR} at (0,0) size 0x0
+        LayoutTextControl {INPUT} at (0,19) size 193x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+          LayoutFlexibleBox {DIV} at (4,3) size 185x13
+            LayoutBlockFlow {DIV} at (12,0) size 173x13
+        LayoutText {#text} at (193,19) size 4x18
+          text run at (193,19) width 4: " "
+        LayoutBR {BR} at (0,0) size 0x0
+        LayoutTextControl {INPUT} at (0,38) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+          LayoutFlexibleBox {DIV} at (4,3) size 125x13
+            LayoutBlockFlow {DIV} at (12,0) size 113x13
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutBlockFlow {P} at (0,107) size 784x18
+        LayoutText {#text} at (0,0) size 37x18
+          text run at (0,0) width 37: "PASS"
+layer at (24,45) size 113x13 scrollX 1.00 scrollWidth 115
+  LayoutBlockFlow {DIV} at (0,0) size 113x13
+    LayoutText {#text} at (-1,0) size 115x13
+      text run at (-1,0) width 21 RTL: " \x{5D5}\x{5D6}\x{5D4}\x{5D5}"
+      text run at (19,0) width 9: "B"
+      text run at (27,0) width 43 RTL: " \x{5D5}\x{5D4}\x{5D9}\x{5D0} \x{5D6}\x{5D4} "
+      text run at (69,0) width 8: "A"
+      text run at (76,0) width 37 RTL: "\x{5D4}\x{5D5}\x{5D0} \x{5D6}\x{5D4} "
+layer at (24,64) size 173x13
+  LayoutBlockFlow {DIV} at (0,0) size 173x13
+    LayoutText {#text} at (58,0) size 115x13
+      text run at (58,0) width 22 RTL: " \x{5D5}\x{5D6}\x{5D4}\x{5D5}"
+      text run at (79,0) width 9: "B"
+      text run at (87,0) width 43 RTL: " \x{5D5}\x{5D4}\x{5D9}\x{5D0} \x{5D6}\x{5D4} "
+      text run at (129,0) width 8: "A"
+      text run at (136,0) width 37 RTL: "\x{5D4}\x{5D5}\x{5D0} \x{5D6}\x{5D4} "
+layer at (24,83) size 113x13
+  LayoutBlockFlow {DIV} at (0,0) size 113x13
+layer at (12,46) size 11x11 transparent
+  LayoutBlockFlow {DIV} at (0,1) size 11x11
+layer at (12,65) size 11x11 transparent
+  LayoutBlockFlow {DIV} at (0,1) size 11x11
+layer at (12,84) size 11x11 transparent
+  LayoutBlockFlow {DIV} at (0,1) size 11x11
+caret: position 0 of child 0 {DIV} of child 0 {DIV} of child 0 {DIV} of {#document-fragment} of child 9 {INPUT} of child 3 {P} of body
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/searchfield-heights-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/searchfield-heights-expected.txt
new file mode 100644
index 0000000..9df5ced
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/searchfield-heights-expected.txt
@@ -0,0 +1,40 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutText {#text} at (0,0) size 376x18
+        text run at (0,0) width 376: "This tests that aqua-style search fields do not honor height."
+      LayoutBR {BR} at (375,14) size 1x0
+      LayoutTextControl {INPUT} at (0,23) size 110x15 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutFlexibleBox {DIV} at (3,2) size 104x11
+          LayoutBlockFlow {DIV} at (0,0) size 94x11
+      LayoutText {#text} at (110,20) size 4x18
+        text run at (110,20) width 4: " "
+      LayoutTextControl {INPUT} at (114,20) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutFlexibleBox {DIV} at (4,3) size 125x13
+          LayoutBlockFlow {DIV} at (0,0) size 113x13
+      LayoutText {#text} at (247,20) size 4x18
+        text run at (247,20) width 4: " "
+      LayoutTextControl {INPUT} at (251,18) size 156x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutFlexibleBox {DIV} at (5,3) size 146x16
+          LayoutBlockFlow {DIV} at (0,0) size 131x16
+      LayoutText {#text} at (0,0) size 0x0
+layer at (11,33) size 94x11
+  LayoutBlockFlow {DIV} at (0,0) size 94x11
+    LayoutText {#text} at (0,0) size 18x11
+      text run at (0,0) width 18: "mini"
+layer at (126,31) size 113x13
+  LayoutBlockFlow {DIV} at (0,0) size 113x13
+    LayoutText {#text} at (0,0) size 27x13
+      text run at (0,0) width 27: "small"
+layer at (264,29) size 131x16
+  LayoutBlockFlow {DIV} at (0,0) size 131x16
+    LayoutText {#text} at (0,0) size 44x16
+      text run at (0,0) width 44: "regular"
+layer at (106,34) size 9x9 transparent
+  LayoutBlockFlow {DIV} at (95,1) size 9x9
+layer at (240,32) size 11x11 transparent
+  LayoutBlockFlow {DIV} at (114,1) size 11x11
+layer at (396,30) size 14x14 transparent
+  LayoutBlockFlow {DIV} at (132,1) size 14x14
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/control-restrict-line-height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/control-restrict-line-height-expected.png
deleted file mode 100644
index cd7646b3..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/control-restrict-line-height-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/control-restrict-line-height-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/control-restrict-line-height-expected.txt
deleted file mode 100644
index 5e922d89..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/control-restrict-line-height-expected.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutText {#text} at (0,0) size 533x18
-        text run at (0,0) width 533: "This tests that we don't honor line-height for controls that have restricted font size. "
-      LayoutBR {BR} at (0,0) size 0x0
-      LayoutMenuList {SELECT} at (0,19) size 299x18 [bgcolor=#F8F8F8]
-        LayoutBlockFlow (anonymous) at (0,0) size 299x18
-          LayoutText (anonymous) at (8,2) size 268x13
-            text run at (8,2) width 268: "This text should be centered vertically in the button"
-      LayoutText {#text} at (299,18) size 4x18
-        text run at (299,18) width 4: " "
-      LayoutBR {BR} at (0,0) size 0x0
-      LayoutButton {INPUT} at (0,38) size 283.41x18 [bgcolor=#FFFFFF]
-        LayoutBlockFlow (anonymous) at (8,2) size 267.41x13
-          LayoutText {#text} at (0,0) size 268x13
-            text run at (0,0) width 268: "This text should be centered vertically in the button"
-      LayoutText {#text} at (283,37) size 5x18
-        text run at (283,37) width 5: " "
-      LayoutBR {BR} at (0,0) size 0x0
-      LayoutTextControl {INPUT} at (0,56) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-        LayoutFlexibleBox {DIV} at (4,3) size 125x13
-          LayoutBlockFlow {DIV} at (0,0) size 113x13
-      LayoutText {#text} at (0,0) size 0x0
-layer at (12,67) size 113x13 scrollWidth 268
-  LayoutBlockFlow {DIV} at (0,0) size 113x13
-    LayoutText {#text} at (0,0) size 268x13
-      text run at (0,0) width 268: "This text should be centered vertically in the button"
-layer at (126,68) size 11x11 transparent
-  LayoutBlockFlow {DIV} at (114,1) size 11x11
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/input-appearance-height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/input-appearance-height-expected.png
index bd877ca7..87229435 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/input-appearance-height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/input-appearance-height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/input-appearance-height-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/input-appearance-height-expected.txt
deleted file mode 100644
index 54b6e32..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/input-appearance-height-expected.txt
+++ /dev/null
@@ -1,106 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x576
-      LayoutBlockFlow (anonymous) at (0,0) size 784x18
-        LayoutText {#text} at (0,0) size 781x18
-          text run at (0,0) width 781: "This tests the height attribute of form elements. The only element that should honour this value is the Image type of input."
-      LayoutBlockFlow {FORM} at (0,18) size 784x229
-        LayoutText {#text} at (0,0) size 37x18
-          text run at (0,0) width 37: "input "
-        LayoutTextControl {INPUT} at (36.89,0) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-        LayoutText {#text} at (167,0) size 5x18
-          text run at (167,0) width 5: " "
-        LayoutBR {BR} at (171,14) size 1x0
-        LayoutText {#text} at (0,19) size 28x18
-          text run at (0,19) width 28: "text "
-        LayoutTextControl {INPUT} at (27.98,19) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-        LayoutText {#text} at (158,19) size 5x18
-          text run at (158,19) width 5: " "
-        LayoutBR {BR} at (162,33) size 1x0
-        LayoutText {#text} at (0,38) size 66x18
-          text run at (0,38) width 66: "checkbox "
-        LayoutBlockFlow {INPUT} at (68.19,42) size 12x12
-        LayoutText {#text} at (83,38) size 5x18
-          text run at (83,38) width 5: " "
-        LayoutBR {BR} at (87,52) size 1x0
-        LayoutText {#text} at (0,57) size 25x18
-          text run at (0,57) width 25: "file "
-        LayoutFileUploadControl {INPUT} at (24.44,58) size 236x18 "No file chosen"
-          LayoutButton {INPUT} at (0,0) size 76.61x18 [bgcolor=#FFFFFF]
-            LayoutBlockFlow (anonymous) at (8,2) size 60.61x13
-              LayoutText {#text} at (0,0) size 61x13
-                text run at (0,0) width 61: "Choose File"
-        LayoutText {#text} at (260,57) size 5x18
-          text run at (260,57) width 5: " "
-        LayoutBR {BR} at (264,71) size 1x0
-        LayoutText {#text} at (0,76) size 44x18
-          text run at (0,76) width 44: "image "
-        LayoutImage {INPUT} at (43.09,89) size 10x1
-        LayoutText {#text} at (53,76) size 5x18
-          text run at (53,76) width 5: " "
-        LayoutBR {BR} at (57,90) size 1x0
-        LayoutText {#text} at (0,94) size 37x18
-          text run at (0,94) width 37: "radio "
-        LayoutBlockFlow {INPUT} at (39.77,97) size 12x13
-        LayoutText {#text} at (54,94) size 5x18
-          text run at (54,94) width 5: " "
-        LayoutBR {BR} at (58,108) size 1x0
-        LayoutText {#text} at (0,116) size 40x18
-          text run at (0,116) width 40: "range "
-        LayoutSlider {INPUT} at (41.53,115) size 129x15 [color=#909090] [bgcolor=#FFFFFF]
-          LayoutFlexibleBox {DIV} at (0,0) size 129x15
-            LayoutBlockFlow {DIV} at (0,0) size 129x15
-              LayoutBlockFlow {DIV} at (57,0) size 15x15
-        LayoutText {#text} at (172,116) size 5x18
-          text run at (172,116) width 5: " "
-        LayoutBR {BR} at (176,130) size 1x0
-        LayoutText {#text} at (0,134) size 35x18
-          text run at (0,134) width 35: "reset "
-        LayoutButton {INPUT} at (34.20,135) size 45.36x18 [bgcolor=#FFFFFF]
-          LayoutBlockFlow (anonymous) at (8,2) size 29.36x13
-            LayoutText {#text} at (0,0) size 30x13
-              text run at (0,0) width 30: "Reset"
-        LayoutText {#text} at (79,134) size 5x18
-          text run at (79,134) width 5: " "
-        LayoutBR {BR} at (83,148) size 1x0
-        LayoutText {#text} at (0,153) size 48x18
-          text run at (0,153) width 48: "submit "
-        LayoutButton {INPUT} at (47.56,154) size 52.47x18 [bgcolor=#FFFFFF]
-          LayoutBlockFlow (anonymous) at (8,2) size 36.47x13
-            LayoutText {#text} at (0,0) size 37x13
-              text run at (0,0) width 37: "Submit"
-        LayoutText {#text} at (100,153) size 5x18
-          text run at (100,153) width 5: " "
-        LayoutBR {BR} at (104,167) size 1x0
-        LayoutText {#text} at (0,172) size 51x18
-          text run at (0,172) width 51: "isindex "
-        LayoutTextControl {INPUT} at (50.22,172) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-        LayoutText {#text} at (181,172) size 5x18
-          text run at (181,172) width 5: " "
-        LayoutBR {BR} at (185,186) size 1x0
-        LayoutText {#text} at (0,191) size 65x18
-          text run at (0,191) width 65: "password "
-        LayoutTextControl {INPUT} at (64.44,191) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-        LayoutText {#text} at (195,191) size 5x18
-          text run at (195,191) width 5: " "
-        LayoutBR {BR} at (199,205) size 1x0
-        LayoutText {#text} at (0,210) size 45x18
-          text run at (0,210) width 45: "search "
-        LayoutTextControl {INPUT} at (44.86,210) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (4,3) size 125x13
-            LayoutBlockFlow {DIV} at (0,0) size 113x13
-        LayoutText {#text} at (0,0) size 0x0
-layer at (48,29) size 125x13
-  LayoutBlockFlow {DIV} at (3,3) size 125x13
-layer at (39,48) size 125x13
-  LayoutBlockFlow {DIV} at (3,3) size 125x13
-layer at (61,201) size 125x13
-  LayoutBlockFlow {DIV} at (3,3) size 125x13
-layer at (75,220) size 125x13
-  LayoutBlockFlow {DIV} at (3,3) size 125x13
-layer at (57,239) size 113x13
-  LayoutBlockFlow {DIV} at (0,0) size 113x13
-layer at (171,240) size 11x11 transparent
-  LayoutBlockFlow {DIV} at (114,1) size 11x11
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/placeholder-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/placeholder-position-expected.png
deleted file mode 100644
index 68da93f71..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/placeholder-position-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/placeholder-position-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/placeholder-position-expected.txt
deleted file mode 100644
index 5b3127a..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/placeholder-position-expected.txt
+++ /dev/null
@@ -1,180 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutTextControl {INPUT} at (0,0) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-        LayoutFlexibleBox {DIV} at (4,3) size 125x13
-          LayoutBlockFlow {DIV} at (0,0) size 113x13
-      LayoutText {#text} at (133,0) size 4x18
-        text run at (133,0) width 4: " "
-      LayoutBR {BR} at (137,14) size 0x0
-      LayoutTextControl {INPUT} at (0,19) size 71x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-      LayoutText {#text} at (71,19) size 4x18
-        text run at (71,19) width 4: " "
-      LayoutTextControl {INPUT} at (75,19) size 71x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-      LayoutText {#text} at (146,19) size 4x18
-        text run at (146,19) width 4: " "
-      LayoutTextControl {INPUT} at (150,19) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-      LayoutText {#text} at (281,19) size 4x18
-        text run at (281,19) width 4: " "
-      LayoutBR {BR} at (285,33) size 0x0
-      LayoutTextControl {INPUT} at (0,38) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-        LayoutFlexibleBox {DIV} at (4,3) size 125x13
-          LayoutBlockFlow {DIV} at (12,0) size 113x13
-      LayoutBR {BR} at (133,52) size 0x0
-      LayoutTextControl {INPUT} at (0,57) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-        LayoutFlexibleBox {DIV} at (4,3) size 125x13
-          LayoutBlockFlow {DIV} at (0,0) size 113x13
-      LayoutBR {BR} at (133,71) size 0x0
-      LayoutBR {BR} at (141,108) size 0x0
-      LayoutTextControl {INPUT} at (0,108) size 131x33 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-      LayoutBR {BR} at (131,122) size 0x0
-      LayoutBR {BR} at (141,186) size 0x0
-      LayoutTextControl {INPUT} at (5,191) size 179x30 [bgcolor=#FFFFFF] [border: (5px solid #000000)]
-      LayoutBR {BR} at (189,212) size 0x0
-      LayoutTextControl {INPUT} at (0,226) size 131x31 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-      LayoutText {#text} at (131,232) size 4x18
-        text run at (131,232) width 4: " "
-      LayoutTextControl {INPUT} at (135,226) size 131x31 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-      LayoutText {#text} at (266,232) size 4x18
-        text run at (266,232) width 4: " "
-      LayoutTextControl {INPUT} at (270,229) size 131x25 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-      LayoutText {#text} at (401,232) size 4x18
-        text run at (401,232) width 4: " "
-      LayoutTextControl {INPUT} at (405,229) size 131x25 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-      LayoutText {#text} at (536,232) size 4x18
-        text run at (536,232) width 4: " "
-      LayoutTextControl {INPUT} at (540,229) size 131x25 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-      LayoutText {#text} at (671,232) size 4x18
-        text run at (671,232) width 4: " "
-      LayoutBR {BR} at (0,0) size 0x0
-      LayoutTextControl {INPUT} at (0,257) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-      LayoutText {#text} at (131,257) size 4x18
-        text run at (131,257) width 4: " "
-      LayoutTextControl {INPUT} at (135,257) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-      LayoutText {#text} at (266,257) size 4x18
-        text run at (266,257) width 4: " "
-      LayoutTextControl {INPUT} at (270,257) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-      LayoutText {#text} at (401,257) size 4x18
-        text run at (401,257) width 4: " "
-      LayoutBR {BR} at (405,271) size 0x0
-      LayoutBR {BR} at (131,304) size 0x0
-layer at (12,11) size 113x13
-  LayoutBlockFlow {DIV} at (4,3) size 113x13 [color=#757575]
-    LayoutText {#text} at (0,0) size 62x13
-      text run at (0,0) width 62: "placeholder"
-layer at (12,11) size 113x13
-  LayoutBlockFlow {DIV} at (0,0) size 113x13
-layer at (11,30) size 65x13
-  LayoutBlockFlow {DIV} at (3,3) size 65x13 [color=#757575]
-    LayoutText {#text} at (0,0) size 62x13
-      text run at (0,0) width 62: "placeholder"
-layer at (11,30) size 65x13
-  LayoutBlockFlow {DIV} at (3,3) size 65x13
-layer at (86,30) size 65x13
-  LayoutBlockFlow {DIV} at (3,3) size 65x13 [color=#757575]
-    LayoutText {#text} at (0,0) size 62x13
-      text run at (0,0) width 62: "placeholder"
-layer at (86,30) size 65x13
-  LayoutBlockFlow {DIV} at (3,3) size 65x13
-layer at (161,30) size 125x13
-  LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575]
-    LayoutText {#text} at (0,0) size 95x13
-      text run at (0,0) width 95: "\x{65E5}\x{672C}\x{8A9E}placeholder"
-layer at (161,30) size 125x13
-  LayoutBlockFlow {DIV} at (3,3) size 125x13
-layer at (24,49) size 113x13
-  LayoutBlockFlow {DIV} at (16,3) size 113x13 [color=#757575]
-    LayoutText {#text} at (52,0) size 61x13
-      text run at (52,0) width 61: "placeholder"
-layer at (24,49) size 113x13
-  LayoutBlockFlow {DIV} at (0,0) size 113x13
-layer at (12,68) size 113x13
-  LayoutBlockFlow {DIV} at (4,3) size 113x13 [color=#757575]
-    LayoutText {#text} at (0,0) size 62x13
-      text run at (0,0) width 62: "placeholder"
-layer at (12,68) size 113x13
-  LayoutBlockFlow {DIV} at (0,0) size 113x13
-layer at (8,84) size 141x32 clip at (9,85) size 139x30
-  LayoutTextControl {TEXTAREA} at (0,76) size 141x32 [bgcolor=#FFFFFF] [border: (1px solid #000000)]
-    LayoutBlockFlow {DIV} at (3,3) size 135x13 [color=#757575]
-      LayoutText {#text} at (0,0) size 62x13
-        text run at (0,0) width 62: "placeholder"
-    LayoutBlockFlow {DIV} at (3,3) size 135x13
-layer at (11,119) size 125x13
-  LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575]
-    LayoutText {#text} at (0,0) size 62x13
-      text run at (0,0) width 62: "placeholder"
-layer at (11,119) size 125x13
-  LayoutBlockFlow {DIV} at (3,3) size 125x13
-layer at (8,149) size 141x45 clip at (9,150) size 139x43
-  LayoutTextControl {TEXTAREA} at (0,141) size 141x45 [bgcolor=#FFFFFF] [border: (1px solid #000000)]
-    LayoutBlockFlow {DIV} at (3,16) size 135x13 [color=#757575]
-      LayoutText {#text} at (0,0) size 62x13
-        text run at (0,0) width 62: "placeholder"
-    LayoutBlockFlow {DIV} at (3,16) size 135x13
-layer at (19,205) size 167x18
-  LayoutBlockFlow {DIV} at (6,6) size 167x18 [color=#757575]
-    LayoutText {#text} at (0,0) size 84x18
-      text run at (0,0) width 84: "placeholder"
-layer at (19,205) size 167x18
-  LayoutBlockFlow {DIV} at (6,6) size 167x18
-layer at (11,237) size 125x25
-  LayoutBlockFlow {DIV} at (3,3) size 125x25
-    LayoutText {#text} at (0,6) size 29x13
-      text run at (0,6) width 29: "Value"
-layer at (146,243) size 125x13
-  LayoutBlockFlow {DIV} at (3,9) size 125x13 [color=#757575]
-    LayoutText {#text} at (0,0) size 62x13
-      text run at (0,0) width 62: "placeholder"
-layer at (146,237) size 125x25
-  LayoutBlockFlow {DIV} at (3,3) size 125x25
-layer at (281,243) size 125x13
-  LayoutBlockFlow {DIV} at (3,6) size 125x13 [color=#757575]
-    LayoutText {#text} at (0,0) size 62x13
-      text run at (0,0) width 62: "placeholder"
-layer at (281,243) size 125x13
-  LayoutBlockFlow {DIV} at (3,6) size 125x13
-layer at (416,243) size 125x13
-  LayoutBlockFlow {DIV} at (3,6) size 125x13 [color=#757575]
-    LayoutText {#text} at (0,0) size 62x13
-      text run at (0,0) width 62: "placeholder"
-layer at (416,237) size 125x25
-  LayoutBlockFlow {DIV} at (3,0) size 125x25
-layer at (551,243) size 125x13
-  LayoutBlockFlow {DIV} at (3,6) size 125x13 [color=#757575]
-    LayoutText {#text} at (0,0) size 62x13
-      text run at (0,0) width 62: "placeholder"
-layer at (551,243) size 125x13
-  LayoutBlockFlow {DIV} at (3,6) size 125x13
-layer at (11,268) size 125x13
-  LayoutBlockFlow {DIV} at (3,3) size 125x13
-    LayoutText {#text} at (48,0) size 29x13
-      text run at (48,0) width 29: "Value"
-layer at (146,268) size 125x13
-  LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575]
-    LayoutText {#text} at (31,0) size 62x13
-      text run at (31,0) width 62: "placeholder"
-layer at (146,268) size 125x13
-  LayoutBlockFlow {DIV} at (3,3) size 125x13
-layer at (281,268) size 125x13
-  LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575]
-    LayoutText {#text} at (31,0) size 62x13
-      text run at (31,0) width 62: "placeholder"
-layer at (281,268) size 125x13
-  LayoutBlockFlow {DIV} at (3,3) size 125x13
-layer at (126,12) size 11x11 transparent
-  LayoutBlockFlow {DIV} at (114,1) size 11x11
-layer at (12,50) size 11x11 transparent
-  LayoutBlockFlow {DIV} at (0,1) size 11x11
-layer at (126,69) size 11x11 transparent
-  LayoutBlockFlow {DIV} at (114,1) size 11x11
-layer at (8,284) size 131x33 clip at (10,286) size 127x29
-  LayoutTextControl {INPUT} at (0,276) size 131x33 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-layer at (11,301) size 125x13 backgroundClip at (27,301) size 109x13 clip at (27,301) size 109x13
-  LayoutBlockFlow {DIV} at (3,17) size 125x13 [color=#757575]
-    LayoutText {#text} at (0,0) size 62x13
-      text run at (0,0) width 62: "placeholder"
-layer at (11,301) size 125x13 backgroundClip at (27,301) size 109x13 clip at (27,301) size 109x13
-  LayoutBlockFlow {DIV} at (3,17) size 125x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.png
deleted file mode 100644
index acf9689..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.txt
deleted file mode 100644
index 750d3de..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.txt
+++ /dev/null
@@ -1,201 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x365
-  LayoutBlockFlow {HTML} at (0,0) size 800x365
-    LayoutBlockFlow {BODY} at (8,8) size 784x349
-      LayoutBlockFlow (anonymous) at (0,0) size 784x83
-        LayoutTextControl {INPUT} at (4,4) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (4,3) size 125x13
-            LayoutBlockFlow {DIV} at (0,0) size 113x13
-        LayoutText {#text} at (141,4) size 4x18
-          text run at (141,4) width 4: " "
-        LayoutTextControl {INPUT} at (149,4) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (4,3) size 125x13
-            LayoutBlockFlow {DIV} at (0,0) size 113x13
-            LayoutBlockFlow {DIV} at (114,1) size 11x11
-        LayoutBR {BR} at (286,4) size 0x18
-        LayoutTextControl {INPUT} at (4,31) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (4,3) size 125x13
-            LayoutBlockFlow {DIV} at (0,0) size 113x13
-        LayoutText {#text} at (141,31) size 4x18
-          text run at (141,31) width 4: " "
-        LayoutTextControl {INPUT} at (149,31) size 133x19 [color=#545454] [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (4,3) size 125x13
-            LayoutBlockFlow {DIV} at (0,0) size 113x13
-        LayoutText {#text} at (286,31) size 4x18
-          text run at (286,31) width 4: " "
-        LayoutBR {BR} at (290,31) size 0x18
-        LayoutTextControl {INPUT} at (4,58) size 133x21 [bgcolor=#FFFFFF] [border: (3px solid #00FF00)]
-          LayoutFlexibleBox {DIV} at (4,4) size 125x13
-            LayoutBlockFlow {DIV} at (0,0) size 113x13
-        LayoutText {#text} at (141,59) size 4x18
-          text run at (141,59) width 4: " "
-        LayoutTextControl {INPUT} at (149,59) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (3,3) size 125x13
-            LayoutBlockFlow {DIV} at (0,0) size 113x13
-        LayoutText {#text} at (284,59) size 4x18
-          text run at (284,59) width 4: " "
-        LayoutBR {BR} at (288,59) size 0x18
-      LayoutBlockFlow {DIV} at (0,83) size 163x45 [bgcolor=#888888]
-        LayoutTextControl {INPUT} at (11,9) size 133x19 [bgcolor=#00FF00] [border: (2px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (3,3) size 127x13
-            LayoutBlockFlow {DIV} at (0,0) size 115x13
-        LayoutText {#text} at (0,0) size 0x0
-      LayoutBlockFlow (anonymous) at (0,128) size 784x221
-        LayoutTextControl {INPUT} at (4,4) size 131x19 [border: (2px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (3,3) size 125x13
-            LayoutBlockFlow {DIV} at (0,0) size 113x13
-        LayoutText {#text} at (139,4) size 4x18
-          text run at (139,4) width 4: " "
-        LayoutBR {BR} at (143,4) size 0x18
-        LayoutTextControl {INPUT} at (4,31) size 131x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (3,3) size 125x13
-            LayoutBlockFlow {DIV} at (0,0) size 113x13
-        LayoutText {#text} at (139,31) size 4x18
-          text run at (139,31) width 4: " "
-        LayoutBR {BR} at (143,31) size 0x18
-        LayoutTextControl {INPUT} at (4,58) size 156x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (5,3) size 146x16
-            LayoutBlockFlow {DIV} at (0,0) size 131x16
-        LayoutText {#text} at (164,60) size 4x18
-          text run at (164,60) width 4: " "
-        LayoutTextControl {INPUT} at (172,58) size 156x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (5,3) size 146x16
-            LayoutBlockFlow {DIV} at (0,0) size 131x16
-        LayoutText {#text} at (332,60) size 4x18
-          text run at (332,60) width 4: " "
-        LayoutTextControl {INPUT} at (340,58) size 156x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (5,3) size 146x16
-            LayoutBlockFlow {DIV} at (0,0) size 131x16
-        LayoutText {#text} at (500,60) size 4x18
-          text run at (500,60) width 4: " "
-        LayoutBR {BR} at (504,60) size 0x18
-        LayoutTextControl {INPUT} at (6,98.50) size 196x28 [bgcolor=#FFFFFF] [border: (3px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (4.50,4.50) size 187x19
-            LayoutBlockFlow {DIV} at (0,0) size 169.50x19
-        LayoutText {#text} at (208,105) size 4x18
-          text run at (208,105) width 4: " "
-        LayoutTextControl {INPUT} at (220,92) size 242x38 [bgcolor=#FFFFFF] [border: (4px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (6,6) size 230x26
-            LayoutBlockFlow {DIV} at (0,0) size 206x26
-        LayoutText {#text} at (470,105) size 4x18
-          text run at (470,105) width 4: " "
-        LayoutBR {BR} at (474,105) size 0x18
-        LayoutTextControl {INPUT} at (6,152.50) size 196x28 [bgcolor=#FFFFFF] [border: (3px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (4.50,4.50) size 187x19
-            LayoutBlockFlow {DIV} at (0,0) size 169.50x19
-        LayoutText {#text} at (208,159) size 4x18
-          text run at (208,159) width 4: " "
-        LayoutTextControl {INPUT} at (220,146) size 242x38 [bgcolor=#FFFFFF] [border: (4px inset #EEEEEE)]
-          LayoutFlexibleBox {DIV} at (6,6) size 230x26
-            LayoutBlockFlow {DIV} at (0,0) size 206x26
-        LayoutText {#text} at (470,159) size 4x18
-          text run at (470,159) width 4: " "
-        LayoutBR {BR} at (474,159) size 0x18
-        LayoutTextControl {INPUT} at (4,196) size 166x21 [bgcolor=#FFFFFF] [border: (1px solid #BDC7D8)]
-          LayoutFlexibleBox {DIV} at (18,4) size 144x13
-            LayoutBlockFlow {DIV} at (0,0) size 132x13
-        LayoutText {#text} at (0,0) size 0x0
-layer at (16,15) size 113x13
-  LayoutBlockFlow {DIV} at (0,0) size 113x13
-    LayoutText {#text} at (0,0) size 17x13
-      text run at (0,0) width 17: "foo"
-layer at (161,15) size 113x13
-  LayoutBlockFlow {DIV} at (0,0) size 113x13
-    LayoutText {#text} at (0,0) size 17x13
-      text run at (0,0) width 17: "foo"
-layer at (16,42) size 113x13
-  LayoutBlockFlow {DIV} at (0,0) size 113x13
-    LayoutText {#text} at (0,0) size 17x13
-      text run at (0,0) width 17: "foo"
-layer at (161,42) size 113x13
-  LayoutBlockFlow {DIV} at (0,0) size 113x13
-    LayoutText {#text} at (0,0) size 17x13
-      text run at (0,0) width 17: "foo"
-layer at (16,70) size 113x13
-  LayoutBlockFlow {DIV} at (0,0) size 113x13
-    LayoutText {#text} at (0,0) size 17x13
-      text run at (0,0) width 17: "foo"
-layer at (160,70) size 113x13
-  LayoutBlockFlow {DIV} at (0,0) size 113x13
-    LayoutText {#text} at (0,0) size 17x13
-      text run at (0,0) width 17: "foo"
-layer at (22,103) size 115x13
-  LayoutBlockFlow {DIV} at (0,0) size 115x13
-    LayoutText {#text} at (0,0) size 59x13
-      text run at (0,0) width 59: "default text"
-layer at (15,143) size 113x13
-  LayoutBlockFlow {DIV} at (0,0) size 113x13
-    LayoutText {#text} at (0,0) size 17x13
-      text run at (0,0) width 17: "foo"
-layer at (15,170) size 113x13
-  LayoutBlockFlow {DIV} at (0,0) size 113x13
-    LayoutText {#text} at (0,0) size 17x13
-      text run at (0,0) width 17: "foo"
-layer at (17,197) size 131x16
-  LayoutBlockFlow {DIV} at (0,0) size 131x16
-    LayoutText {#text} at (0,0) size 20x16
-      text run at (0,0) width 20: "foo"
-layer at (185,197) size 131x16
-  LayoutBlockFlow {DIV} at (0,0) size 131x16
-    LayoutText {#text} at (0,0) size 20x16
-      text run at (0,0) width 20: "foo"
-layer at (353,197) size 131x16
-  LayoutBlockFlow {DIV} at (0,0) size 131x16
-    LayoutText {#text} at (0,0) size 20x16
-      text run at (0,0) width 20: "foo"
-layer at (19,239) size 170x19 backgroundClip at (19,239) size 169x19 clip at (19,239) size 169x19
-  LayoutBlockFlow {DIV} at (0,0) size 169.50x19
-    LayoutText {#text} at (0,0) size 26x19
-      text run at (0,0) width 26: "foo"
-layer at (234,234) size 206x26
-  LayoutBlockFlow {DIV} at (0,0) size 206x26
-    LayoutText {#text} at (0,0) size 31x26
-      text run at (0,0) width 31: "foo"
-layer at (19,293) size 170x19 backgroundClip at (19,293) size 169x19 clip at (19,293) size 169x19
-  LayoutBlockFlow {DIV} at (0,0) size 169.50x19
-    LayoutText {#text} at (0,0) size 26x19
-      text run at (0,0) width 26: "foo"
-layer at (234,288) size 206x26
-  LayoutBlockFlow {DIV} at (0,0) size 206x26
-    LayoutText {#text} at (0,0) size 31x26
-      text run at (0,0) width 31: "foo"
-layer at (30,336) size 132x13
-  LayoutBlockFlow {DIV} at (18,4) size 132x13 [color=#757575]
-    LayoutText {#text} at (0,0) size 92x13
-      text run at (0,0) width 92: "Search for Events"
-layer at (30,336) size 132x13
-  LayoutBlockFlow {DIV} at (0,0) size 132x13
-layer at (130,16) size 11x11 transparent
-  LayoutBlockFlow {DIV} at (114,1) size 11x11
-layer at (130,43) size 11x11 transparent
-  LayoutBlockFlow {DIV} at (114,1) size 11x11
-layer at (275,43) size 11x11 transparent
-  LayoutBlockFlow {DIV} at (114,1) size 11x11
-layer at (130,71) size 11x11 transparent
-  LayoutBlockFlow {DIV} at (114,1) size 11x11
-layer at (274,71) size 11x11 transparent
-  LayoutBlockFlow {DIV} at (114,1) size 11x11
-layer at (138,104) size 11x11 transparent
-  LayoutBlockFlow {DIV} at (116,1) size 11x11
-layer at (129,144) size 11x11 transparent
-  LayoutBlockFlow {DIV} at (114,1) size 11x11
-layer at (129,171) size 11x11 transparent
-  LayoutBlockFlow {DIV} at (114,1) size 11x11
-layer at (149,198) size 14x14 transparent
-  LayoutBlockFlow {DIV} at (132,1) size 14x14
-layer at (317,198) size 14x14 transparent
-  LayoutBlockFlow {DIV} at (132,1) size 14x14
-layer at (485,198) size 14x14 transparent
-  LayoutBlockFlow {DIV} at (132,1) size 14x14
-layer at (190,241) size 16x16 transparent
-  LayoutBlockFlow {DIV} at (171,1.50) size 16x16
-layer at (442,236) size 22x22 transparent
-  LayoutBlockFlow {DIV} at (208,2) size 22x22
-layer at (190,295) size 16x16 transparent
-  LayoutBlockFlow {DIV} at (171,1.50) size 16x16
-layer at (442,290) size 22x22 transparent
-  LayoutBlockFlow {DIV} at (208,2) size 22x22
-layer at (163,337) size 11x11 transparent
-  LayoutBlockFlow {DIV} at (133,1) size 11x11
-caret: position 0 of child 0 {#text} of child 0 {DIV} of child 0 {DIV} of child 0 {DIV} of {#document-fragment} of child 10 {INPUT} of body
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-cancel-button-style-sharing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-cancel-button-style-sharing-expected.png
deleted file mode 100644
index 37620a2..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-cancel-button-style-sharing-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-rtl-expected.png
deleted file mode 100644
index 40ca375..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-rtl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/searchfield-heights-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/searchfield-heights-expected.png
deleted file mode 100644
index d6b2dcc..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/searchfield-heights-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.png
index 0e1641f..e3ac520e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.txt
index 07653909..9ec60640 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/control-restrict-line-height-expected.txt
@@ -6,27 +6,27 @@
       LayoutText {#text} at (0,0) size 533x18
         text run at (0,0) width 533: "This tests that we don't honor line-height for controls that have restricted font size. "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutMenuList {SELECT} at (0,19) size 299x18 [bgcolor=#F8F8F8]
-        LayoutBlockFlow (anonymous) at (0,0) size 299x18
-          LayoutText (anonymous) at (8,2) size 268x13
-            text run at (8,2) width 268: "This text should be centered vertically in the button"
-      LayoutText {#text} at (299,18) size 4x18
-        text run at (299,18) width 4: " "
+      LayoutMenuList {SELECT} at (0,19) size 302x18 [bgcolor=#F8F8F8]
+        LayoutBlockFlow (anonymous) at (0,0) size 302x18
+          LayoutText (anonymous) at (8,2) size 271x13
+            text run at (8,2) width 271: "This text should be centered vertically in the button"
+      LayoutText {#text} at (302,18) size 4x18
+        text run at (302,18) width 4: " "
       LayoutBR {BR} at (0,0) size 0x0
-      LayoutButton {INPUT} at (0,38) size 283.92x18 [bgcolor=#FFFFFF]
-        LayoutBlockFlow (anonymous) at (8,2) size 267.92x13
-          LayoutText {#text} at (0,0) size 268x13
-            text run at (0,0) width 268: "This text should be centered vertically in the button"
-      LayoutText {#text} at (283,37) size 5x18
-        text run at (283,37) width 5: " "
+      LayoutButton {INPUT} at (0,38) size 286.83x18 [bgcolor=#FFFFFF]
+        LayoutBlockFlow (anonymous) at (8,2) size 270.83x13
+          LayoutText {#text} at (0,0) size 271x13
+            text run at (0,0) width 271: "This text should be centered vertically in the button"
+      LayoutText {#text} at (286,37) size 5x18
+        text run at (286,37) width 5: " "
       LayoutBR {BR} at (0,0) size 0x0
       LayoutTextControl {INPUT} at (0,56) size 133x19 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
         LayoutFlexibleBox {DIV} at (4,3) size 125x13
           LayoutBlockFlow {DIV} at (0,0) size 113x13
       LayoutText {#text} at (0,0) size 0x0
-layer at (12,67) size 113x13 scrollWidth 269
+layer at (12,67) size 113x13 scrollWidth 272
   LayoutBlockFlow {DIV} at (0,0) size 113x13
-    LayoutText {#text} at (0,0) size 268x13
-      text run at (0,0) width 268: "This text should be centered vertically in the button"
+    LayoutText {#text} at (0,0) size 271x13
+      text run at (0,0) width 271: "This text should be centered vertically in the button"
 layer at (126,68) size 11x11 transparent
   LayoutBlockFlow {DIV} at (114,1) size 11x11
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.png
index e03080d..efbf395 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.txt
index 950df077..eec843f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/input-appearance-height-expected.txt
@@ -27,14 +27,14 @@
         LayoutBR {BR} at (87,52) size 1x0
         LayoutText {#text} at (0,57) size 25x18
           text run at (0,57) width 25: "file "
-        LayoutFileUploadControl {INPUT} at (24.44,58) size 236x18 "No file chosen"
-          LayoutButton {INPUT} at (0,0) size 76.61x18 [bgcolor=#FFFFFF]
-            LayoutBlockFlow (anonymous) at (8,2) size 60.61x13
-              LayoutText {#text} at (0,0) size 61x13
-                text run at (0,0) width 61: "Choose File"
-        LayoutText {#text} at (260,57) size 5x18
-          text run at (260,57) width 5: " "
-        LayoutBR {BR} at (264,71) size 1x0
+        LayoutFileUploadControl {INPUT} at (24.44,58) size 238x18 "No file chosen"
+          LayoutButton {INPUT} at (0,0) size 77.33x18 [bgcolor=#FFFFFF]
+            LayoutBlockFlow (anonymous) at (8,2) size 61.33x13
+              LayoutText {#text} at (0,0) size 62x13
+                text run at (0,0) width 62: "Choose File"
+        LayoutText {#text} at (262,57) size 5x18
+          text run at (262,57) width 5: " "
+        LayoutBR {BR} at (266,71) size 1x0
         LayoutText {#text} at (0,76) size 44x18
           text run at (0,76) width 44: "image "
         LayoutImage {INPUT} at (43.09,89) size 10x1
@@ -58,8 +58,8 @@
         LayoutBR {BR} at (176,130) size 1x0
         LayoutText {#text} at (0,134) size 35x18
           text run at (0,134) width 35: "reset "
-        LayoutButton {INPUT} at (34.20,135) size 45.52x18 [bgcolor=#FFFFFF]
-          LayoutBlockFlow (anonymous) at (8,2) size 29.52x13
+        LayoutButton {INPUT} at (34.20,135) size 45.67x18 [bgcolor=#FFFFFF]
+          LayoutBlockFlow (anonymous) at (8,2) size 29.67x13
             LayoutText {#text} at (0,0) size 30x13
               text run at (0,0) width 30: "Reset"
         LayoutText {#text} at (79,134) size 5x18
@@ -67,8 +67,8 @@
         LayoutBR {BR} at (83,148) size 1x0
         LayoutText {#text} at (0,153) size 48x18
           text run at (0,153) width 48: "submit "
-        LayoutButton {INPUT} at (47.56,154) size 52.47x18 [bgcolor=#FFFFFF]
-          LayoutBlockFlow (anonymous) at (8,2) size 36.47x13
+        LayoutButton {INPUT} at (47.56,154) size 52.86x18 [bgcolor=#FFFFFF]
+          LayoutBlockFlow (anonymous) at (8,2) size 36.86x13
             LayoutText {#text} at (0,0) size 37x13
               text run at (0,0) width 37: "Submit"
         LayoutText {#text} at (100,153) size 5x18
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.png
index b04157f5..e57a131f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.txt
index 04ae42ff..d3a59ba 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/placeholder-position-expected.txt
@@ -80,8 +80,8 @@
   LayoutBlockFlow {DIV} at (3,3) size 65x13
 layer at (161,30) size 125x13
   LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575]
-    LayoutText {#text} at (0,0) size 95x13
-      text run at (0,0) width 95: "\x{65E5}\x{672C}\x{8A9E}placeholder"
+    LayoutText {#text} at (0,0) size 96x13
+      text run at (0,0) width 96: "\x{65E5}\x{672C}\x{8A9E}placeholder"
 layer at (161,30) size 125x13
   LayoutBlockFlow {DIV} at (3,3) size 125x13
 layer at (24,49) size 113x13
@@ -116,8 +116,8 @@
     LayoutBlockFlow {DIV} at (3,16) size 135x13
 layer at (19,205) size 167x18
   LayoutBlockFlow {DIV} at (6,6) size 167x18 [color=#757575]
-    LayoutText {#text} at (0,0) size 84x18
-      text run at (0,0) width 84: "placeholder"
+    LayoutText {#text} at (0,0) size 81x18
+      text run at (0,0) width 81: "placeholder"
 layer at (19,205) size 167x18
   LayoutBlockFlow {DIV} at (6,6) size 167x18
 layer at (11,237) size 125x25
@@ -154,14 +154,14 @@
       text run at (48,0) width 29: "Value"
 layer at (146,268) size 125x13
   LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575]
-    LayoutText {#text} at (31,0) size 62x13
-      text run at (31,0) width 62: "placeholder"
+    LayoutText {#text} at (31,0) size 63x13
+      text run at (31,0) width 63: "placeholder"
 layer at (146,268) size 125x13
   LayoutBlockFlow {DIV} at (3,3) size 125x13
 layer at (281,268) size 125x13
   LayoutBlockFlow {DIV} at (3,3) size 125x13 [color=#757575]
-    LayoutText {#text} at (31,0) size 62x13
-      text run at (31,0) width 62: "placeholder"
+    LayoutText {#text} at (31,0) size 63x13
+      text run at (31,0) width 63: "placeholder"
 layer at (281,268) size 125x13
   LayoutBlockFlow {DIV} at (3,3) size 125x13
 layer at (126,12) size 11x11 transparent
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.png
index c5adc19d..ab528ab 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.txt
index a39ced5..081b3f831 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.txt
@@ -134,32 +134,32 @@
       text run at (0,0) width 17: "foo"
 layer at (17,197) size 131x16
   LayoutBlockFlow {DIV} at (0,0) size 131x16
-    LayoutText {#text} at (0,0) size 21x16
-      text run at (0,0) width 21: "foo"
+    LayoutText {#text} at (0,0) size 20x16
+      text run at (0,0) width 20: "foo"
 layer at (185,197) size 131x16
   LayoutBlockFlow {DIV} at (0,0) size 131x16
-    LayoutText {#text} at (0,0) size 21x16
-      text run at (0,0) width 21: "foo"
+    LayoutText {#text} at (0,0) size 20x16
+      text run at (0,0) width 20: "foo"
 layer at (353,197) size 131x16
   LayoutBlockFlow {DIV} at (0,0) size 131x16
-    LayoutText {#text} at (0,0) size 21x16
-      text run at (0,0) width 21: "foo"
+    LayoutText {#text} at (0,0) size 20x16
+      text run at (0,0) width 20: "foo"
 layer at (19,239) size 170x19 backgroundClip at (19,239) size 169x19 clip at (19,239) size 169x19
   LayoutBlockFlow {DIV} at (0,0) size 169.50x19
-    LayoutText {#text} at (0,0) size 26x19
-      text run at (0,0) width 26: "foo"
+    LayoutText {#text} at (0,0) size 25x19
+      text run at (0,0) width 25: "foo"
 layer at (234,234) size 206x26
   LayoutBlockFlow {DIV} at (0,0) size 206x26
-    LayoutText {#text} at (0,0) size 31x26
-      text run at (0,0) width 31: "foo"
+    LayoutText {#text} at (0,0) size 32x26
+      text run at (0,0) width 32: "foo"
 layer at (19,293) size 170x19 backgroundClip at (19,293) size 169x19 clip at (19,293) size 169x19
   LayoutBlockFlow {DIV} at (0,0) size 169.50x19
-    LayoutText {#text} at (0,0) size 26x19
-      text run at (0,0) width 26: "foo"
+    LayoutText {#text} at (0,0) size 25x19
+      text run at (0,0) width 25: "foo"
 layer at (234,288) size 206x26
   LayoutBlockFlow {DIV} at (0,0) size 206x26
-    LayoutText {#text} at (0,0) size 31x26
-      text run at (0,0) width 31: "foo"
+    LayoutText {#text} at (0,0) size 32x26
+      text run at (0,0) width 32: "foo"
 layer at (30,336) size 132x13
   LayoutBlockFlow {DIV} at (18,4) size 132x13 [color=#757575]
     LayoutText {#text} at (0,0) size 92x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-cancel-button-style-sharing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-cancel-button-style-sharing-expected.png
index 467b065..318beb4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-cancel-button-style-sharing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-cancel-button-style-sharing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.png
index 62b30cd..830368ac 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.txt
index 16f973e..61c6801 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-rtl-expected.txt
@@ -35,20 +35,20 @@
       LayoutBlockFlow {P} at (0,107) size 784x18
         LayoutText {#text} at (0,0) size 37x18
           text run at (0,0) width 37: "PASS"
-layer at (24,45) size 113x13 scrollX 1.00 scrollWidth 115
+layer at (24,45) size 113x13 scrollX 2.00 scrollWidth 115
   LayoutBlockFlow {DIV} at (0,0) size 113x13
-    LayoutText {#text} at (-1,0) size 115x13
-      text run at (-1,0) width 21 RTL: " \x{5D5}\x{5D6}\x{5D4}\x{5D5}"
-      text run at (19,0) width 9: "B"
-      text run at (27,0) width 43 RTL: " \x{5D5}\x{5D4}\x{5D9}\x{5D0} \x{5D6}\x{5D4} "
+    LayoutText {#text} at (-2,0) size 116x13
+      text run at (-2,0) width 22 RTL: " \x{5D5}\x{5D6}\x{5D4}\x{5D5}"
+      text run at (19,0) width 8: "B"
+      text run at (26,0) width 44 RTL: " \x{5D5}\x{5D4}\x{5D9}\x{5D0} \x{5D6}\x{5D4} "
       text run at (69,0) width 8: "A"
       text run at (76,0) width 37 RTL: "\x{5D4}\x{5D5}\x{5D0} \x{5D6}\x{5D4} "
 layer at (24,64) size 173x13
   LayoutBlockFlow {DIV} at (0,0) size 173x13
-    LayoutText {#text} at (58,0) size 115x13
-      text run at (58,0) width 22 RTL: " \x{5D5}\x{5D6}\x{5D4}\x{5D5}"
-      text run at (79,0) width 9: "B"
-      text run at (87,0) width 43 RTL: " \x{5D5}\x{5D4}\x{5D9}\x{5D0} \x{5D6}\x{5D4} "
+    LayoutText {#text} at (57,0) size 116x13
+      text run at (57,0) width 23 RTL: " \x{5D5}\x{5D6}\x{5D4}\x{5D5}"
+      text run at (79,0) width 8: "B"
+      text run at (86,0) width 44 RTL: " \x{5D5}\x{5D4}\x{5D9}\x{5D0} \x{5D6}\x{5D4} "
       text run at (129,0) width 8: "A"
       text run at (136,0) width 37 RTL: "\x{5D4}\x{5D5}\x{5D0} \x{5D6}\x{5D4} "
 layer at (24,83) size 113x13
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.png
index a912409..89fc5d0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.txt
index 9df5ced..c5ba5cc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/searchfield-heights-expected.txt
@@ -22,16 +22,16 @@
       LayoutText {#text} at (0,0) size 0x0
 layer at (11,33) size 94x11
   LayoutBlockFlow {DIV} at (0,0) size 94x11
-    LayoutText {#text} at (0,0) size 18x11
-      text run at (0,0) width 18: "mini"
+    LayoutText {#text} at (0,0) size 19x11
+      text run at (0,0) width 19: "mini"
 layer at (126,31) size 113x13
   LayoutBlockFlow {DIV} at (0,0) size 113x13
-    LayoutText {#text} at (0,0) size 27x13
-      text run at (0,0) width 27: "small"
+    LayoutText {#text} at (0,0) size 28x13
+      text run at (0,0) width 28: "small"
 layer at (264,29) size 131x16
   LayoutBlockFlow {DIV} at (0,0) size 131x16
-    LayoutText {#text} at (0,0) size 44x16
-      text run at (0,0) width 44: "regular"
+    LayoutText {#text} at (0,0) size 43x16
+      text run at (0,0) width 43: "regular"
 layer at (106,34) size 9x9 transparent
   LayoutBlockFlow {DIV} at (95,1) size 9x9
 layer at (240,32) size 11x11 transparent
diff --git a/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.html b/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.html
index 8451acf..75342ce 100644
--- a/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.html
+++ b/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.html
@@ -1,5 +1,6 @@
 <html>
 <head>
+<script src="../../resources/gc.js"></script>
 <script src="resources/database-common.js"></script>
 <script src="multiple-databases-garbage-collection.js"></script>
 <body onload="setupAndRunTest();">
diff --git a/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.js b/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.js
index ba47b0b..ebd7aa7 100644
--- a/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.js
+++ b/third_party/WebKit/LayoutTests/storage/websql/multiple-databases-garbage-collection.js
@@ -1,15 +1,3 @@
-function GC()
-{
-    // Force GC.
-    if (window.GCController)
-        GCController.collectAll();
-    else {
-        for (var i = 0; i < 10000; ++i) {
-            ({ });
-        }
-    }
-}
-
 // Variable for the database that will never be forgotten
 var persistentDB = 0;
 // Variable for the forgotten database
@@ -32,12 +20,12 @@
     }, function(err) {
         log("Forgotten Database Transaction Errored - " + err);
         forgottenDB = 0;
-        GC();
+        gc();
         checkCompletion();
     }, function() {
         log("Forgotten Database Transaction Complete");
         forgottenDB = 0;
-        GC();
+        gc();
         checkCompletion();
     });
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py
index 516ba12..c228acf 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/android.py
@@ -29,13 +29,12 @@
 import itertools
 import logging
 import os
+import posixpath
 import re
 import sys
 import threading
 import time
 
-from multiprocessing.pool import ThreadPool
-
 from webkitpy.common import exit_codes
 from webkitpy.common.system.executive import ScriptError
 from webkitpy.layout_tests.breakpad.dump_reader_multipart import DumpReaderAndroid
@@ -218,9 +217,6 @@
     def library_name(self):
         return 'libcontent_shell_content_view.so'
 
-    def additional_resources(self):
-        return []
-
     def command_line_file(self):
         return '/data/local/tmp/content-shell-command-line'
 
@@ -374,50 +370,131 @@
         return self._check_devices(printer)
 
     def _check_devices(self, printer):
-        # Printer objects aren't threadsafe, so we need to protect calls to them.
-        lock = threading.Lock()
-        pool = None
 
         # Push the executables and other files to the devices; doing this now
         # means we can do this in parallel in the manager process and not mix
         # this in with starting and stopping workers.
-        def setup_device(worker_number):
-            d = self.create_driver(worker_number)
-            serial = d._device.serial  # pylint: disable=protected-access
 
-            def log_safely(msg, throttled=True):
-                if throttled:
-                    callback = printer.write_throttled_update
-                else:
-                    callback = printer.write_update
-                with lock:
-                    callback('[%s] %s' % (serial, msg))
+        lock = threading.Lock()
 
+        def log_safely(msg, throttled=True):
+            if throttled:
+                callback = printer.write_throttled_update
+            else:
+                callback = printer.write_update
+            with lock:
+                callback('%s' % msg)
+
+        def _setup_device_impl(device):
             log_safely('preparing device', throttled=False)
+
+            if self._devices.is_device_prepared(device.serial):
+                return
+
+            device.EnableRoot()
+            perf_control.PerfControl(device).SetPerfProfilingMode()
+
+            # Required by webkit_support::GetWebKitRootDirFilePath().
+            # Other directories will be created automatically by adb push.
+            device.RunShellCommand(
+                ['mkdir', '-p', DEVICE_SOURCE_ROOT_DIR + 'chrome'],
+                check_return=True)
+
+            # Allow the test driver to get full read and write access to the directory on the device,
+            # as well as for the FIFOs. We'll need a world writable directory.
+            device.RunShellCommand(
+                ['mkdir', '-p', self._driver_details.device_directory()],
+                check_return=True)
+
+            # Make sure that the disk cache on the device resets to a clean state.
+            device.RunShellCommand(
+                ['rm', '-rf', self._driver_details.device_cache_directory()],
+                check_return=True)
+
+            device.EnableRoot()
+            perf_control.PerfControl(device).SetPerfProfilingMode()
+
+            # Required by webkit_support::GetWebKitRootDirFilePath().
+            # Other directories will be created automatically by adb push.
+            device.RunShellCommand(
+                ['mkdir', '-p', DEVICE_SOURCE_ROOT_DIR + 'chrome'],
+                check_return=True)
+
+            # Allow the test driver to get full read and write access to the directory on the device,
+            # as well as for the FIFOs. We'll need a world writable directory.
+            device.RunShellCommand(
+                ['mkdir', '-p', self._driver_details.device_directory()],
+                check_return=True)
+
+            # Make sure that the disk cache on the device resets to a clean state.
+            device.RunShellCommand(
+                ['rm', '-rf', self._driver_details.device_cache_directory()],
+                check_return=True)
+
+            device_path = lambda *p: posixpath.join(
+                self._driver_details.device_directory(), *p)
+
+            device.Install(self._path_to_driver())
+
+            # Build up a list of what we want to push, including:
+            host_device_tuples = []
+
+            # - the custom font files
+            host_device_tuples.append(
+                (self._build_path('android_main_fonts.xml'),
+                 device_path('android_main_fonts.xml')))
+            host_device_tuples.append(
+                (self._build_path('android_fallback_fonts.xml'),
+                 device_path('android_fallback_fonts.xml')))
+            host_device_tuples.append(
+                (self._build_path('AHEM____.TTF'),
+                 device_path('fonts', 'AHEM____.TTF')))
+            for (host_dirs, font_file, _) in HOST_FONT_FILES:
+                for host_dir in host_dirs:
+                    host_font_path = host_dir + font_file
+                    if self._check_file_exists(host_font_path, '', more_logging=False):
+                        host_device_tuples.append(
+                            (host_font_path,
+                             device_path('fonts', font_file)))
+
+            # - the test resources
+            host_device_tuples.extend(
+                (self.host.filesystem.join(self.layout_tests_dir(), resource),
+                 posixpath.join(DEVICE_LAYOUT_TESTS_DIR, resource))
+                for resource in TEST_RESOURCES_TO_PUSH)
+
+            # ... and then push them to the device.
+            device.PushChangedFiles(host_device_tuples)
+
+            device.RunShellCommand(
+                ['mkdir', '-p', self._driver_details.device_fifo_directory()],
+                check_return=True)
+
+            device.RunShellCommand(
+                ['chmod', '-R', '777', self._driver_details.device_directory()],
+                check_return=True)
+            device.RunShellCommand(
+                ['chmod', '-R', '777', self._driver_details.device_fifo_directory()],
+                check_return=True)
+
+            # Mark this device as having been set up.
+            self._devices.set_device_prepared(device.serial)
+
+            log_safely('device prepared', throttled=False)
+
+        def setup_device(device):
             try:
-                d._setup_test(log_safely)
-                log_safely('device prepared', throttled=False)
-            except (ScriptError, driver.DeviceFailure) as error:
+                _setup_device_impl(device)
+            except (ScriptError,
+                    driver.DeviceFailure,
+                    device_errors.CommandFailedError,
+                    device_errors.CommandTimeoutError,
+                    device_errors.DeviceUnreachableError) as error:
                 with lock:
                     _log.warning('[%s] failed to prepare_device: %s', serial, error)
-            except KeyboardInterrupt:
-                if pool:
-                    pool.terminate()
 
-        # FIXME: It would be nice if we knew how many workers we needed.
-        num_workers = self.default_child_processes()
-        num_child_processes = int(self.get_option('child_processes'))
-        if num_child_processes:
-            num_workers = min(num_workers, num_child_processes)
-        if num_workers > 1:
-            pool = ThreadPool(num_workers)
-            try:
-                pool.map(setup_device, range(num_workers))
-            except KeyboardInterrupt:
-                pool.terminate()
-                raise
-        else:
-            setup_device(0)
+        devices = self._devices.usable_devices(self.host.executive)
+        device_utils.DeviceUtils.parallel(devices).pMap(setup_device)
 
         if not self._devices.prepared_devices():
             _log.error('Could not prepare any devices for testing.')
@@ -711,55 +788,6 @@
 
         return symfs_path
 
-    def _push_data_if_needed(self, log_callback):
-        self._push_executable(log_callback)
-        self._push_fonts(log_callback)
-        self._push_test_resources(log_callback)
-
-    def _setup_test(self, log_callback):
-        # FIXME: Move this routine and its subroutines off of the AndroidDriver
-        # class and onto some other helper class, so that we
-        # can initialize the device without needing to create a driver.
-
-        if self._android_devices.is_device_prepared(self._device.serial):
-            return
-
-        self._device.EnableRoot()
-        self._setup_performance()
-
-        # Required by webkit_support::GetWebKitRootDirFilePath().
-        # Other directories will be created automatically by adb push.
-        self._device.RunShellCommand(
-            ['mkdir', '-p', DEVICE_SOURCE_ROOT_DIR + 'chrome'],
-            check_return=True)
-
-        # Allow the test driver to get full read and write access to the directory on the device,
-        # as well as for the FIFOs. We'll need a world writable directory.
-        self._device.RunShellCommand(
-            ['mkdir', '-p', self._driver_details.device_directory()],
-            check_return=True)
-
-        # Make sure that the disk cache on the device resets to a clean state.
-        self._device.RunShellCommand(
-            ['rm', '-rf', self._driver_details.device_cache_directory()],
-            check_return=True)
-
-        self._push_data_if_needed(log_callback)
-
-        self._device.RunShellCommand(
-            ['mkdir', '-p', self._driver_details.device_fifo_directory()],
-            check_return=True)
-
-        self._device.RunShellCommand(
-            ['chmod', '-R', '777', self._driver_details.device_directory()],
-            check_return=True)
-        self._device.RunShellCommand(
-            ['chmod', '-R', '777', self._driver_details.device_fifo_directory()],
-            check_return=True)
-
-        # Mark this device as having been set up.
-        self._android_devices.set_device_prepared(self._device.serial)
-
     def _log_error(self, message):
         _log.error('[%s] %s', self._device.serial, message)
 
@@ -774,45 +802,6 @@
         self._device_failed = True
         raise driver.DeviceFailure('[%s] %s' % (self._device.serial, message))
 
-    def _push_file_if_needed(self, host_file, device_file, log_callback):
-        basename = self._port.host.filesystem.basename(host_file)
-        log_callback('checking %s' % basename)
-        self._device.PushChangedFiles([(host_file, device_file)])
-
-    def _push_executable(self, log_callback):
-        for resource in self._driver_details.additional_resources():
-            self._push_file_if_needed(self._port._build_path(
-                resource), self._driver_details.device_directory() + resource, log_callback)
-
-        self._push_file_if_needed(self._port._build_path('android_main_fonts.xml'),
-                                  self._driver_details.device_directory() + 'android_main_fonts.xml', log_callback)
-        self._push_file_if_needed(self._port._build_path('android_fallback_fonts.xml'),
-                                  self._driver_details.device_directory() + 'android_fallback_fonts.xml', log_callback)
-
-        try:
-            driver_host_path = self._port._path_to_driver()  # pylint: disable=protected-access
-            log_callback('installing apk if necessary')
-            self._device.Install(driver_host_path)
-        except (device_errors.CommandFailedError,
-                device_errors.CommandTimeoutError,
-                device_errors.DeviceUnreachableError) as exc:
-            self._abort('Failed to install %s onto device: %s' % (driver_host_path, str(exc)))
-
-    def _push_fonts(self, log_callback):
-        path_to_ahem_font = self._port._build_path('AHEM____.TTF')
-        self._push_file_if_needed(path_to_ahem_font, self._driver_details.device_fonts_directory() + 'AHEM____.TTF', log_callback)
-        for (host_dirs, font_file, _) in HOST_FONT_FILES:
-            for host_dir in host_dirs:
-                host_font_path = host_dir + font_file
-                if self._port._check_file_exists(host_font_path, '', more_logging=False):
-                    self._push_file_if_needed(
-                        host_font_path, self._driver_details.device_fonts_directory() + font_file, log_callback)
-
-    def _push_test_resources(self, log_callback):
-        for resource in TEST_RESOURCES_TO_PUSH:
-            self._push_file_if_needed(self._port.layout_tests_dir() + '/' + resource,
-                                      DEVICE_LAYOUT_TESTS_DIR + resource, log_callback)
-
     def _get_last_stacktrace(self):
         try:
             tombstones = self._device.RunShellCommand(
@@ -854,10 +843,6 @@
     def _get_logcat(self):
         return '\n'.join(self._device.adb.Logcat(dump=True, logcat_format='threadtime'))
 
-    def _setup_performance(self):
-        # Disable CPU scaling and drop ram cache to reduce noise in tests
-        perf_control.PerfControl(self._device).SetPerfProfilingMode()
-
     def _teardown_performance(self):
         perf_control.PerfControl(self._device).SetDefaultPerfMode()
 
diff --git a/tools/code_coverage/OWNERS b/tools/code_coverage/OWNERS
new file mode 100644
index 0000000..9fd85c05
--- /dev/null
+++ b/tools/code_coverage/OWNERS
@@ -0,0 +1,3 @@
+liaoyuke@chromium.org
+mmoroz@chromium.org
+inferno@chromum.org
diff --git a/tools/code_coverage/coverage.py b/tools/code_coverage/coverage.py
new file mode 100755
index 0000000..e6d245e
--- /dev/null
+++ b/tools/code_coverage/coverage.py
@@ -0,0 +1,470 @@
+#!/usr/bin/python
+# 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.
+
+"""Script to generate Clang source based code coverage report.
+
+  NOTE: This script must be called from the root of checkout, and because it
+  requires building with gn arg "is_component_build=false", the build is not
+  compatible with sanitizer flags (such as "is_asan" and "is_msan") and flag
+  "optimize_for_fuzzing".
+
+  Example usages:
+  python tools/code_coverage/coverage.py crypto_unittests url_unittests
+  -b out/Coverage -o out/report -c 'out/Coverage/crypto_unittests'
+  -c 'out/Coverage/url_unittests --gtest_filter=URLParser.PathURL'
+  # Generate code coverage report for crypto_unittests and url_unittests and
+  # all generated artifacts are stored in out/report. For url_unittests, only
+  # run test URLParser.PathURL.
+
+  For more options, please refer to tools/coverage/coverage.py -h for help.
+"""
+
+from __future__ import print_function
+
+import sys
+
+import argparse
+import os
+import subprocess
+import threading
+import urllib2
+
+sys.path.append(os.path.join(os.path.dirname(__file__), os.path.pardir,
+                             os.path.pardir, 'tools', 'clang', 'scripts'))
+
+import update as clang_update
+
+# Absolute path to the root of the checkout.
+SRC_ROOT_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__),
+                                             os.path.pardir, os.path.pardir))
+
+# Absolute path to the code coverage tools binary.
+LLVM_BUILD_DIR = clang_update.LLVM_BUILD_DIR
+LLVM_COV_PATH = os.path.join(LLVM_BUILD_DIR, 'bin', 'llvm-cov')
+LLVM_PROFDATA_PATH = os.path.join(LLVM_BUILD_DIR, 'bin', 'llvm-profdata')
+
+# Build directory, the value is parsed from command line arguments.
+BUILD_DIR = None
+
+# Output directory for generated artifacts, the value is parsed from command
+# line arguemnts.
+OUTPUT_DIR = None
+
+# Default number of jobs used to build when goma is configured and enabled.
+DEFAULT_GOMA_JOBS = 100
+
+# Name of the file extension for profraw data files.
+PROFRAW_FILE_EXTENSION = 'profraw'
+
+# Name of the final profdata file, and this file needs to be passed to
+# "llvm-cov" command in order to call "llvm-cov show" to inspect the
+# line-by-line coverage of specific files.
+PROFDATA_FILE_NAME = 'coverage.profdata'
+
+# Build arg required for generating code coverage data.
+CLANG_COVERAGE_BUILD_ARG = 'use_clang_coverage'
+
+# A set of targets that depend on target "testing/gtest", this set is generated
+# by 'gn refs "testing/gtest"', and it is lazily initialized when needed.
+GTEST_TARGET_NAMES = None
+
+
+# TODO(crbug.com/759794): remove this function once tools get included to
+# Clang bundle:
+# https://chromium-review.googlesource.com/c/chromium/src/+/688221
+def DownloadCoverageToolsIfNeeded():
+  """Temporary solution to download llvm-profdata and llvm-cov tools."""
+  def _GetRevisionFromStampFile(stamp_file_path):
+    """Returns a pair of revision number by reading the build stamp file.
+
+    Args:
+      stamp_file_path: A path the build stamp file created by
+                       tools/clang/scripts/update.py.
+    Returns:
+      A pair of integers represeting the main and sub revision respectively.
+    """
+    if not os.path.exists(stamp_file_path):
+      return 0, 0
+
+    with open(stamp_file_path) as stamp_file:
+      revision_stamp_data = stamp_file.readline().strip().split('-')
+    return int(revision_stamp_data[0]), int(revision_stamp_data[1])
+
+  clang_revision, clang_sub_revision = _GetRevisionFromStampFile(
+      clang_update.STAMP_FILE)
+
+  coverage_revision_stamp_file = os.path.join(
+      os.path.dirname(clang_update.STAMP_FILE), 'cr_coverage_revision')
+  coverage_revision, coverage_sub_revision = _GetRevisionFromStampFile(
+      coverage_revision_stamp_file)
+
+  if (coverage_revision == clang_revision and
+      coverage_sub_revision == clang_sub_revision):
+    # LLVM coverage tools are up to date, bail out.
+    return clang_revision
+
+  package_version = '%d-%d' % (clang_revision, clang_sub_revision)
+  coverage_tools_file = 'llvm-code-coverage-%s.tgz' % package_version
+
+  # The code bellow follows the code from tools/clang/scripts/update.py.
+  if sys.platform == 'win32' or sys.platform == 'cygwin':
+    coverage_tools_url = clang_update.CDS_URL + '/Win/' + coverage_tools_file
+  elif sys.platform == 'darwin':
+    coverage_tools_url = clang_update.CDS_URL + '/Mac/' + coverage_tools_file
+  else:
+    assert sys.platform.startswith('linux')
+    coverage_tools_url = (
+        clang_update.CDS_URL + '/Linux_x64/' + coverage_tools_file)
+
+  try:
+    clang_update.DownloadAndUnpack(coverage_tools_url,
+                                   clang_update.LLVM_BUILD_DIR)
+    print('Coverage tools %s unpacked' % package_version)
+    with open(coverage_revision_stamp_file, 'w') as file_handle:
+      file_handle.write(package_version)
+      file_handle.write('\n')
+  except urllib2.URLError:
+    raise Exception(
+        'Failed to download coverage tools: %s.' % coverage_tools_url)
+
+
+def _GenerateLineByLineFileCoverageInHtml(binary_paths, profdata_file_path):
+  """Generates per file line-by-line coverage in html using 'llvm-cov show'.
+
+  For a file with absolute path /a/b/x.cc, a html report is generated as:
+  OUTPUT_DIR/coverage/a/b/x.cc.html. An index html file is also generated as:
+  OUTPUT_DIR/index.html.
+
+  Args:
+    binary_paths: A list of paths to the instrumented binaries.
+    profdata_file_path: A path to the profdata file.
+  """
+  print('Generating per file line by line code coverage in html')
+
+  # llvm-cov show [options] -instr-profile PROFILE BIN [-object BIN,...]
+  # [[-object BIN]] [SOURCES]
+  # NOTE: For object files, the first one is specified as a positional argument,
+  # and the rest are specified as keyword argument.
+  subprocess_cmd = [LLVM_COV_PATH, 'show', '-format=html',
+                    '-output-dir={}'.format(OUTPUT_DIR),
+                    '-instr-profile={}'.format(profdata_file_path),
+                    binary_paths[0]]
+  subprocess_cmd.extend(['-object=' + binary_path
+                         for binary_path in binary_paths[1:]])
+
+  subprocess.check_call(subprocess_cmd)
+
+
+def _CreateCoverageProfileDataForTargets(targets, commands, jobs_count=None):
+  """Builds and runs target to generate the coverage profile data.
+
+  Args:
+    targets: A list of targets to build with coverage instrumentation.
+    commands: A list of commands used to run the targets.
+    jobs_count: Number of jobs to run in parallel for building. If None, a
+                default value is derived based on CPUs availability.
+
+  Returns:
+    A relative path to the generated profdata file.
+  """
+  _BuildTargets(targets, jobs_count)
+  profraw_file_paths = _GetProfileRawDataPathsByExecutingCommands(targets,
+                                                                  commands)
+  profdata_file_path = _CreateCoverageProfileDataFromProfRawData(
+      profraw_file_paths)
+
+  return profdata_file_path
+
+
+def _BuildTargets(targets, jobs_count):
+  """Builds target with Clang coverage instrumentation.
+
+  This function requires current working directory to be the root of checkout.
+
+  Args:
+    targets: A list of targets to build with coverage instrumentation.
+    jobs_count: Number of jobs to run in parallel for compilation. If None, a
+                default value is derived based on CPUs availability.
+
+
+  """
+  def _IsGomaConfigured():
+    """Returns True if goma is enabled in the gn build args.
+
+    Returns:
+      A boolean indicates whether goma is configured for building or not.
+    """
+    build_args = _ParseArgsGnFile()
+    return 'use_goma' in build_args and build_args['use_goma'] == 'true'
+
+  print('Building %s' % str(targets))
+
+  if jobs_count is None and _IsGomaConfigured():
+    jobs_count = DEFAULT_GOMA_JOBS
+
+  subprocess_cmd = ['ninja', '-C', BUILD_DIR]
+  if jobs_count is not None:
+    subprocess_cmd.append('-j' + str(jobs_count))
+
+  subprocess_cmd.extend(targets)
+  subprocess.check_call(subprocess_cmd)
+
+
+def _GetProfileRawDataPathsByExecutingCommands(targets, commands):
+  """Runs commands and returns the relative paths to the profraw data files.
+
+  Args:
+    targets: A list of targets built with coverage instrumentation.
+    commands: A list of commands used to run the targets.
+
+  Returns:
+    A list of relative paths to the generated profraw data files.
+  """
+  # Remove existing profraw data files.
+  for file_or_dir in os.listdir(OUTPUT_DIR):
+    if file_or_dir.endswith(PROFRAW_FILE_EXTENSION):
+      os.remove(os.path.join(OUTPUT_DIR, file_or_dir))
+
+  # Run different test targets in parallel to generate profraw data files.
+  threads = []
+  for target, command in zip(targets, commands):
+    thread = threading.Thread(target=_ExecuteCommand, args=(target, command))
+    thread.start()
+    threads.append(thread)
+  for thread in threads:
+    thread.join()
+
+  profraw_file_paths = []
+  for file_or_dir in os.listdir(OUTPUT_DIR):
+    if file_or_dir.endswith(PROFRAW_FILE_EXTENSION):
+      profraw_file_paths.append(os.path.join(OUTPUT_DIR, file_or_dir))
+
+  # Assert one target/command generates at least one profraw data file.
+  for target in targets:
+    assert any(os.path.basename(profraw_file).startswith(target) for
+               profraw_file in profraw_file_paths), ('Running target: %s '
+                                                     'failed to generate any '
+                                                     'profraw data file, '
+                                                     'please make sure the '
+                                                     'binary exists and is '
+                                                     'properly instrumented.'
+                                                     % target)
+
+  return profraw_file_paths
+
+
+def _ExecuteCommand(target, command):
+  """Runs a single command and generates a profraw data file.
+
+  Args:
+    target: A target built with coverage instrumentation.
+    command: A command used to run the target.
+  """
+  if _IsTargetGTestTarget(target):
+    # This test argument is required and only required for gtest unit test
+    # targets because by default, they run tests in parallel, and that won't
+    # generated code coverage data correctly.
+    command += ' --test-launcher-jobs=1'
+
+  expected_profraw_file_name = os.extsep.join([target, '%p',
+                                               PROFRAW_FILE_EXTENSION])
+  expected_profraw_file_path = os.path.join(OUTPUT_DIR,
+                                            expected_profraw_file_name)
+  output_file_name = os.extsep.join([target + '_output', 'txt'])
+  output_file_path = os.path.join(OUTPUT_DIR, output_file_name)
+
+  print('Running command: "%s", the output is redirected to "%s"' %
+        (command, output_file_path))
+  output = subprocess.check_output(command.split(),
+                                   env={'LLVM_PROFILE_FILE':
+                                        expected_profraw_file_path})
+  with open(output_file_path, 'w') as output_file:
+    output_file.write(output)
+
+
+def _CreateCoverageProfileDataFromProfRawData(profraw_file_paths):
+  """Returns a relative path to the profdata file by merging profraw data files.
+
+  Args:
+    profraw_file_paths: A list of relative paths to the profraw data files that
+                        are to be merged.
+
+  Returns:
+    A relative path to the generated profdata file.
+
+  Raises:
+    CalledProcessError: An error occurred merging profraw data files.
+  """
+  print('Creating the profile data file')
+
+  profdata_file_path = os.path.join(OUTPUT_DIR, PROFDATA_FILE_NAME)
+  try:
+    subprocess_cmd = [LLVM_PROFDATA_PATH, 'merge', '-o', profdata_file_path,
+                      '-sparse=true']
+    subprocess_cmd.extend(profraw_file_paths)
+    subprocess.check_call(subprocess_cmd)
+  except subprocess.CalledProcessError as error:
+    print('Failed to merge profraw files to create profdata file')
+    raise error
+
+  return profdata_file_path
+
+
+def _GetBinaryPath(command):
+  """Returns a relative path to the binary to be run by the command.
+
+  Args:
+    command: A command used to run a target.
+
+  Returns:
+    A relative path to the binary.
+  """
+  return command.split()[0]
+
+
+def _IsTargetGTestTarget(target):
+  """Returns True if the target is a gtest target.
+
+  Args:
+    target: A target built with coverage instrumentation.
+
+  Returns:
+    A boolean value indicates whether the target is a gtest target.
+  """
+  global GTEST_TARGET_NAMES
+  if GTEST_TARGET_NAMES is None:
+    output = subprocess.check_output(['gn', 'refs', BUILD_DIR, 'testing/gtest'])
+    list_of_gtest_targets = [gtest_target
+                             for gtest_target in output.splitlines()
+                             if gtest_target]
+    GTEST_TARGET_NAMES = set([gtest_target.split(':')[1]
+                              for gtest_target in list_of_gtest_targets])
+
+  return target in GTEST_TARGET_NAMES
+
+
+def _ValidateCommandsAreRelativeToSrcRoot(commands):
+  for command in commands:
+    binary_path = _GetBinaryPath(command)
+    assert binary_path.startswith(BUILD_DIR), ('Target executable "%s" is '
+                                               'outside of the given build '
+                                               'directory: "%s". Please make '
+                                               'sure the command: "%s" is '
+                                               'relative to the root of the '
+                                               'checkout.'
+                                               %(binary_path, BUILD_DIR,
+                                                 command))
+
+
+def _ValidateBuildingWithClangCoverage():
+  """Asserts that targets are built with Clang coverage enabled."""
+  build_args = _ParseArgsGnFile()
+
+  if (CLANG_COVERAGE_BUILD_ARG not in build_args or
+      build_args[CLANG_COVERAGE_BUILD_ARG] != 'true'):
+    assert False, ('\'{} = true\' is required in args.gn.').format(
+        CLANG_COVERAGE_BUILD_ARG)
+
+
+def _ParseArgsGnFile():
+  """Parses args.gn file and returns results as a dictionary.
+
+  Returns:
+    A dictionary representing the build args.
+  """
+  build_args_path = os.path.join(BUILD_DIR, 'args.gn')
+  assert os.path.exists(build_args_path), ('"%s" is not a build directory, '
+                                           'missing args.gn file.' % BUILD_DIR)
+  with open(build_args_path) as build_args_file:
+    build_args_lines = build_args_file.readlines()
+
+  build_args = {}
+  for build_arg_line in build_args_lines:
+    build_arg_without_comments = build_arg_line.split('#')[0]
+    key_value_pair = build_arg_without_comments.split('=')
+    if len(key_value_pair) != 2:
+      continue
+
+    key = key_value_pair[0].strip()
+    value = key_value_pair[1].strip()
+    build_args[key] = value
+
+  return build_args
+
+
+def _ParseCommandArguments():
+  """Adds and parses relevant arguments for tool comands.
+
+  Returns:
+    A dictionary representing the arguments.
+  """
+  arg_parser = argparse.ArgumentParser()
+  arg_parser.usage = __doc__
+
+  arg_parser.add_argument('-b', '--build-dir', type=str, required=True,
+                          help='The build directory, the path needs to be '
+                               'relative to the root of the checkout.')
+
+  arg_parser.add_argument('-o', '--output-dir', type=str, required=True,
+                          help='Output directory for generated artifacts.')
+
+  arg_parser.add_argument('-c', '--command', action='append',
+                          required=True,
+                          help='Commands used to run test targets, one test '
+                               'target needs one and only one command, when '
+                               'specifying commands, one should assume the '
+                               'current working directory is the root of the '
+                               'checkout.')
+
+  arg_parser.add_argument('-j', '--jobs', type=int, default=None,
+                          help='Run N jobs to build in parallel. If not '
+                               'specified, a default value will be derived '
+                               'based on CPUs availability. Please refer to '
+                               '\'ninja -h\' for more details.')
+
+  arg_parser.add_argument('targets', nargs='+',
+                          help='The names of the test targets to run.')
+
+  args = arg_parser.parse_args()
+  return args
+
+
+def Main():
+  """Execute tool commands."""
+  assert os.path.abspath(os.getcwd()) == SRC_ROOT_PATH, ('This script must be '
+                                                         'called from the root '
+                                                         'of checkout')
+  DownloadCoverageToolsIfNeeded()
+
+  args = _ParseCommandArguments()
+  global BUILD_DIR
+  BUILD_DIR = args.build_dir
+  global OUTPUT_DIR
+  OUTPUT_DIR = args.output_dir
+
+  assert len(args.targets) == len(args.command), ('Number of targets must be '
+                                                  'equal to the number of test '
+                                                  'commands.')
+  assert os.path.exists(BUILD_DIR), ('Build directory: {} doesn\'t exist. '
+                                     'Please run "gn gen" to generate.').format(
+                                         BUILD_DIR)
+  _ValidateBuildingWithClangCoverage()
+  _ValidateCommandsAreRelativeToSrcRoot(args.command)
+  if not os.path.exists(OUTPUT_DIR):
+    os.makedirs(OUTPUT_DIR)
+
+  profdata_file_path = _CreateCoverageProfileDataForTargets(args.targets,
+                                                            args.command,
+                                                            args.jobs)
+
+  binary_paths = [_GetBinaryPath(command) for command in args.command]
+  _GenerateLineByLineFileCoverageInHtml(binary_paths, profdata_file_path)
+  html_index_file_path = 'file://' + os.path.abspath(
+      os.path.join(OUTPUT_DIR, 'index.html'))
+  print('\nCode coverage profile data is created as: %s' % profdata_file_path)
+  print('index file for html report is generated as: %s' % html_index_file_path)
+
+if __name__ == '__main__':
+  sys.exit(Main())
diff --git a/tools/code_coverage/croc.css b/tools/code_coverage/croc.css
deleted file mode 100644
index 071822d..0000000
--- a/tools/code_coverage/croc.css
+++ /dev/null
@@ -1,102 +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.
- */
-
-/*
- * croc.css - styles for croc HTML output
- */
-
-body {
-	font-family:arial;
-}
-
-table {
-	border-collapse:collapse;
-	border-width:0px;
-	border-style:solid;
-}
-
-thead {
-	background-color:#C0C0E0;
-	text-align:center;
-}
-
-td {
-	padding-right:10px;
-	padding-left:10px;
-	font-size:small;
-	border-width:1px;
-	border-style:solid;
-	border-color:black;
-}
-
-td.secdesc {
-	text-align:center;
-	font-size:medium;
-	font-weight:bold;
-	border-width:0px;
-	border-style:none;
-	padding-top:10px;
-	padding-bottom:5px;
-}
-
-td.section {
-	background-color:#D0D0F0;
-	text-align:center;
-}
-
-td.stat {
-	text-align:center;
-}
-
-td.number {
-	text-align:right;
-}
-
-td.graph {
-	/* Hide the dummy character */
-	color:#FFFFFF;
-	padding-left:6px;
-}
-
-td.high_pct {
-	text-align:right;
-	background-color:#B0FFB0;
-}
-td.mid_pct {
-	text-align:right;
-	background-color:#FFFF90;
-}
-td.low_pct {
-	text-align:right;
-	background-color:#FFB0B0;
-}
-
-
-span.missing {
-	background-color:#FFB0B0;
-}
-span.instr {
-	background-color:#FFFF90;
-}
-span.covered {
-	background-color:#B0FFB0;
-}
-
-span.g_missing {
-	background-color:#FF4040;
-}
-span.g_instr {
-	background-color:#FFFF00;
-}
-span.g_covered {
-	background-color:#40FF40;
-}
-
-p.time {
-	padding-top:10px;
-	font-size:small;
-	font-style:italic;
-}
diff --git a/tools/code_coverage/croc.py b/tools/code_coverage/croc.py
deleted file mode 100755
index 1b9908a5..0000000
--- a/tools/code_coverage/croc.py
+++ /dev/null
@@ -1,722 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-"""Crocodile - compute coverage numbers for Chrome coverage dashboard."""
-
-import optparse
-import os
-import platform
-import re
-import sys
-import croc_html
-import croc_scan
-
-
-class CrocError(Exception):
-  """Coverage error."""
-
-
-class CrocStatError(CrocError):
-  """Error evaluating coverage stat."""
-
-#------------------------------------------------------------------------------
-
-
-class CoverageStats(dict):
-  """Coverage statistics."""
-
-  # Default dictionary values for this stat.
-  DEFAULTS = { 'files_covered': 0,
-               'files_instrumented': 0,
-               'files_executable': 0,
-               'lines_covered': 0,
-               'lines_instrumented': 0,
-               'lines_executable': 0 }
-
-  def Add(self, coverage_stats):
-    """Adds a contribution from another coverage stats dict.
-
-    Args:
-      coverage_stats: Statistics to add to this one.
-    """
-    for k, v in coverage_stats.iteritems():
-      if k in self:
-        self[k] += v
-      else:
-        self[k] = v
-
-  def AddDefaults(self):
-    """Add some default stats which might be assumed present.
-
-    Do not clobber if already present.  Adds resilience when evaling a
-    croc file which expects certain stats to exist."""
-    for k, v in self.DEFAULTS.iteritems():
-      if not k in self:
-        self[k] = v
-
-#------------------------------------------------------------------------------
-
-
-class CoveredFile(object):
-  """Information about a single covered file."""
-
-  def __init__(self, filename, **kwargs):
-    """Constructor.
-
-    Args:
-      filename: Full path to file, '/'-delimited.
-      kwargs: Keyword args are attributes for file.
-    """
-    self.filename = filename
-    self.attrs = dict(kwargs)
-
-    # Move these to attrs?
-    self.local_path = None      # Local path to file
-    self.in_lcov = False        # Is file instrumented?
-
-    # No coverage data for file yet
-    self.lines = {}     # line_no -> None=executable, 0=instrumented, 1=covered
-    self.stats = CoverageStats()
-
-  def UpdateCoverage(self):
-    """Updates the coverage summary based on covered lines."""
-    exe = instr = cov = 0
-    for l in self.lines.itervalues():
-      exe += 1
-      if l is not None:
-        instr += 1
-        if l == 1:
-          cov += 1
-
-    # Add stats that always exist
-    self.stats = CoverageStats(lines_executable=exe,
-                               lines_instrumented=instr,
-                               lines_covered=cov,
-                               files_executable=1)
-
-    # Add conditional stats
-    if cov:
-      self.stats['files_covered'] = 1
-    if instr or self.in_lcov:
-      self.stats['files_instrumented'] = 1
-
-#------------------------------------------------------------------------------
-
-
-class CoveredDir(object):
-  """Information about a directory containing covered files."""
-
-  def __init__(self, dirpath):
-    """Constructor.
-
-    Args:
-      dirpath: Full path of directory, '/'-delimited.
-    """
-    self.dirpath = dirpath
-
-    # List of covered files directly in this dir, indexed by filename (not
-    # full path)
-    self.files = {}
-
-    # List of subdirs, indexed by filename (not full path)
-    self.subdirs = {}
-
-    # Dict of CoverageStats objects summarizing all children, indexed by group
-    self.stats_by_group = {'all': CoverageStats()}
-    # TODO: by language
-
-  def GetTree(self, indent=''):
-    """Recursively gets stats for the directory and its children.
-
-    Args:
-      indent: indent prefix string.
-
-    Returns:
-      The tree as a string.
-    """
-    dest = []
-
-    # Compile all groupstats
-    groupstats = []
-    for group in sorted(self.stats_by_group):
-      s = self.stats_by_group[group]
-      if not s.get('lines_executable'):
-        continue        # Skip groups with no executable lines
-      groupstats.append('%s:%d/%d/%d' % (
-          group, s.get('lines_covered', 0),
-          s.get('lines_instrumented', 0),
-          s.get('lines_executable', 0)))
-
-    outline = '%s%-30s   %s' % (indent,
-                                os.path.split(self.dirpath)[1] + '/',
-                                '   '.join(groupstats))
-    dest.append(outline.rstrip())
-
-    for d in sorted(self.subdirs):
-      dest.append(self.subdirs[d].GetTree(indent=indent + '  '))
-
-    return '\n'.join(dest)
-
-#------------------------------------------------------------------------------
-
-
-class Coverage(object):
-  """Code coverage for a group of files."""
-
-  def __init__(self):
-    """Constructor."""
-    self.files = {}             # Map filename --> CoverageFile
-    self.root_dirs = []         # (root, altname)
-    self.rules = []             # (regexp, dict of RHS attrs)
-    self.tree = CoveredDir('')
-    self.print_stats = []       # Dicts of args to PrintStat()
-
-    # Functions which need to be replaced for unit testing
-    self.add_files_walk = os.walk         # Walk function for AddFiles()
-    self.scan_file = croc_scan.ScanFile   # Source scanner for AddFiles()
-
-  def CleanupFilename(self, filename):
-    """Cleans up a filename.
-
-    Args:
-      filename: Input filename.
-
-    Returns:
-      The cleaned up filename.
-
-    Changes all path separators to '/'.
-    Makes relative paths (those starting with '../' or './' absolute.
-    Replaces all instances of root dirs with alternate names.
-    """
-    # Change path separators
-    filename = filename.replace('\\', '/')
-
-    # Windows doesn't care about case sensitivity.
-    if platform.system() in ['Windows', 'Microsoft']:
-      filename = filename.lower()
-
-    # If path is relative, make it absolute
-    # TODO: Perhaps we should default to relative instead, and only understand
-    # absolute to be files starting with '\', '/', or '[A-Za-z]:'?
-    if filename.split('/')[0] in ('.', '..'):
-      filename = os.path.abspath(filename).replace('\\', '/')
-
-    # Replace alternate roots
-    for root, alt_name in self.root_dirs:
-      # Windows doesn't care about case sensitivity.
-      if platform.system() in ['Windows', 'Microsoft']:
-        root = root.lower()
-      filename = re.sub('^' + re.escape(root) + '(?=(/|$))',
-                        alt_name, filename)
-    return filename
-
-  def ClassifyFile(self, filename):
-    """Applies rules to a filename, to see if we care about it.
-
-    Args:
-      filename: Input filename.
-
-    Returns:
-      A dict of attributes for the file, accumulated from the right hand sides
-          of rules which fired.
-    """
-    attrs = {}
-
-    # Process all rules
-    for regexp, rhs_dict in self.rules:
-      if regexp.match(filename):
-        attrs.update(rhs_dict)
-
-    return attrs
-    # TODO: Files can belong to multiple groups?
-    #   (test/source)
-    #   (mac/pc/win)
-    #   (media_test/all_tests)
-    #   (small/med/large)
-    # How to handle that?
-
-  def AddRoot(self, root_path, alt_name='_'):
-    """Adds a root directory.
-
-    Args:
-      root_path: Root directory to add.
-      alt_name: If specified, name of root dir.  Otherwise, defaults to '_'.
-
-    Raises:
-      ValueError: alt_name was blank.
-    """
-    # Alt name must not be blank.  If it were, there wouldn't be a way to
-    # reverse-resolve from a root-replaced path back to the local path, since
-    # '' would always match the beginning of the candidate filename, resulting
-    # in an infinite loop.
-    if not alt_name:
-      raise ValueError('AddRoot alt_name must not be blank.')
-
-    # Clean up root path based on existing rules
-    self.root_dirs.append([self.CleanupFilename(root_path), alt_name])
-
-  def AddRule(self, path_regexp, **kwargs):
-    """Adds a rule.
-
-    Args:
-      path_regexp: Regular expression to match for filenames.  These are
-          matched after root directory replacement.
-      kwargs: Keyword arguments are attributes to set if the rule applies.
-
-    Keyword arguments currently supported:
-      include: If True, includes matches; if False, excludes matches.  Ignored
-          if None.
-      group: If not None, sets group to apply to matches.
-      language: If not None, sets file language to apply to matches.
-    """
-
-    # Compile regexp ahead of time
-    self.rules.append([re.compile(path_regexp), dict(kwargs)])
-
-  def GetCoveredFile(self, filename, add=False):
-    """Gets the CoveredFile object for the filename.
-
-    Args:
-      filename: Name of file to find.
-      add: If True, will add the file if it's not present.  This applies the
-          transformations from AddRoot() and AddRule(), and only adds the file
-          if a rule includes it, and it has a group and language.
-
-    Returns:
-      The matching CoveredFile object, or None if not present.
-    """
-    # Clean filename
-    filename = self.CleanupFilename(filename)
-
-    # Check for existing match
-    if filename in self.files:
-      return self.files[filename]
-
-    # File isn't one we know about.  If we can't add it, give up.
-    if not add:
-      return None
-
-    # Check rules to see if file can be added.  Files must be included and
-    # have a group and language.
-    attrs = self.ClassifyFile(filename)
-    if not (attrs.get('include')
-            and attrs.get('group')
-            and attrs.get('language')):
-      return None
-
-    # Add the file
-    f = CoveredFile(filename, **attrs)
-    self.files[filename] = f
-
-    # Return the newly covered file
-    return f
-
-  def RemoveCoveredFile(self, cov_file):
-    """Removes the file from the covered file list.
-
-    Args:
-      cov_file: A file object returned by GetCoveredFile().
-    """
-    self.files.pop(cov_file.filename)
-
-  def ParseLcovData(self, lcov_data):
-    """Adds coverage from LCOV-formatted data.
-
-    Args:
-      lcov_data: An iterable returning lines of data in LCOV format.  For
-          example, a file or list of strings.
-    """
-    cov_file = None
-    cov_lines = None
-    for line in lcov_data:
-      line = line.strip()
-      if line.startswith('SF:'):
-        # Start of data for a new file; payload is filename
-        cov_file = self.GetCoveredFile(line[3:], add=True)
-        if cov_file:
-          cov_lines = cov_file.lines
-          cov_file.in_lcov = True       # File was instrumented
-      elif not cov_file:
-        # Inside data for a file we don't care about - so skip it
-        pass
-      elif line.startswith('DA:'):
-        # Data point - that is, an executable line in current file
-        line_no, is_covered = map(int, line[3:].split(','))
-        if is_covered:
-          # Line is covered
-          cov_lines[line_no] = 1
-        elif cov_lines.get(line_no) != 1:
-          # Line is not covered, so track it as uncovered
-          cov_lines[line_no] = 0
-      elif line == 'end_of_record':
-        cov_file.UpdateCoverage()
-        cov_file = None
-      # (else ignore other line types)
-
-  def ParseLcovFile(self, input_filename):
-    """Adds coverage data from a .lcov file.
-
-    Args:
-      input_filename: Input filename.
-    """
-    # TODO: All manner of error checking
-    lcov_file = None
-    try:
-      lcov_file = open(input_filename, 'rt')
-      self.ParseLcovData(lcov_file)
-    finally:
-      if lcov_file:
-        lcov_file.close()
-
-  def GetStat(self, stat, group='all', default=None):
-    """Gets a statistic from the coverage object.
-
-    Args:
-      stat: Statistic to get.  May also be an evaluatable python expression,
-          using the stats.  For example, 'stat1 - stat2'.
-      group: File group to match; if 'all', matches all groups.
-      default: Value to return if there was an error evaluating the stat.  For
-          example, if the stat does not exist.  If None, raises
-          CrocStatError.
-
-    Returns:
-      The evaluated stat, or None if error.
-
-    Raises:
-      CrocStatError: Error evaluating stat.
-    """
-    # TODO: specify a subdir to get the stat from, then walk the tree to
-    # print the stats from just that subdir
-
-    # Make sure the group exists
-    if group not in self.tree.stats_by_group:
-      if default is None:
-        raise CrocStatError('Group %r not found.' % group)
-      else:
-        return default
-
-    stats = self.tree.stats_by_group[group]
-    # Unit tests use real dicts, not CoverageStats objects,
-    # so we can't AddDefaults() on them.
-    if group == 'all' and hasattr(stats, 'AddDefaults'):
-      stats.AddDefaults()
-    try:
-      return eval(stat, {'__builtins__': {'S': self.GetStat}}, stats)
-    except Exception, e:
-      if default is None:
-        raise CrocStatError('Error evaluating stat %r: %s' % (stat, e))
-      else:
-        return default
-
-  def PrintStat(self, stat, format=None, outfile=sys.stdout, **kwargs):
-    """Prints a statistic from the coverage object.
-
-    Args:
-      stat: Statistic to get.  May also be an evaluatable python expression,
-          using the stats.  For example, 'stat1 - stat2'.
-      format: Format string to use when printing stat.  If None, prints the
-          stat and its evaluation.
-      outfile: File stream to output stat to; defaults to stdout.
-      kwargs: Additional args to pass to GetStat().
-    """
-    s = self.GetStat(stat, **kwargs)
-    if format is None:
-      outfile.write('GetStat(%r) = %s\n' % (stat, s))
-    else:
-      outfile.write(format % s + '\n')
-
-  def AddFiles(self, src_dir):
-    """Adds files to coverage information.
-
-    LCOV files only contains files which are compiled and instrumented as part
-    of running coverage.  This function finds missing files and adds them.
-
-    Args:
-      src_dir: Directory on disk at which to start search.  May be a relative
-          path on disk starting with '.' or '..', or an absolute path, or a
-          path relative to an alt_name for one of the roots
-          (for example, '_/src').  If the alt_name matches more than one root,
-          all matches will be attempted.
-
-    Note that dirs not underneath one of the root dirs and covered by an
-    inclusion rule will be ignored.
-    """
-    # Check for root dir alt_names in the path and replace with the actual
-    # root dirs, then recurse.
-    found_root = False
-    for root, alt_name in self.root_dirs:
-      replaced_root = re.sub('^' + re.escape(alt_name) + '(?=(/|$))', root,
-                             src_dir)
-      if replaced_root != src_dir:
-        found_root = True
-        self.AddFiles(replaced_root)
-    if found_root:
-      return    # Replaced an alt_name with a root_dir, so already recursed.
-
-    for (dirpath, dirnames, filenames) in self.add_files_walk(src_dir):
-      # Make a copy of the dirnames list so we can modify the original to
-      # prune subdirs we don't need to walk.
-      for d in list(dirnames):
-        # Add trailing '/' to directory names so dir-based regexps can match
-        # '/' instead of needing to specify '(/|$)'.
-        dpath = self.CleanupFilename(dirpath + '/' + d) + '/'
-        attrs = self.ClassifyFile(dpath)
-        if not attrs.get('include'):
-          # Directory has been excluded, so don't traverse it
-          # TODO: Document the slight weirdness caused by this: If you
-          # AddFiles('./A'), and the rules include 'A/B/C/D' but not 'A/B',
-          # then it won't recurse into './A/B' so won't find './A/B/C/D'.
-          # Workarounds are to AddFiles('./A/B/C/D') or AddFiles('./A/B/C').
-          # The latter works because it explicitly walks the contents of the
-          # path passed to AddFiles(), so it finds './A/B/C/D'.
-          dirnames.remove(d)
-
-      for f in filenames:
-        local_path = dirpath + '/' + f
-
-        covf = self.GetCoveredFile(local_path, add=True)
-        if not covf:
-          continue
-
-        # Save where we found the file, for generating line-by-line HTML output
-        covf.local_path = local_path
-
-        if covf.in_lcov:
-          # File already instrumented and doesn't need to be scanned
-          continue
-
-        if not covf.attrs.get('add_if_missing', 1):
-          # Not allowed to add the file
-          self.RemoveCoveredFile(covf)
-          continue
-
-        # Scan file to find potentially-executable lines
-        lines = self.scan_file(covf.local_path, covf.attrs.get('language'))
-        if lines:
-          for l in lines:
-            covf.lines[l] = None
-          covf.UpdateCoverage()
-        else:
-          # File has no executable lines, so don't count it
-          self.RemoveCoveredFile(covf)
-
-  def AddConfig(self, config_data, lcov_queue=None, addfiles_queue=None):
-    """Adds JSON-ish config data.
-
-    Args:
-      config_data: Config data string.
-      lcov_queue: If not None, object to append lcov_files to instead of
-          parsing them immediately.
-      addfiles_queue: If not None, object to append add_files to instead of
-          processing them immediately.
-    """
-    # TODO: All manner of error checking
-    cfg = eval(config_data, {'__builtins__': {}}, {})
-
-    for rootdict in cfg.get('roots', []):
-      self.AddRoot(rootdict['root'], alt_name=rootdict.get('altname', '_'))
-
-    for ruledict in cfg.get('rules', []):
-      regexp = ruledict.pop('regexp')
-      self.AddRule(regexp, **ruledict)
-
-    for add_lcov in cfg.get('lcov_files', []):
-      if lcov_queue is not None:
-        lcov_queue.append(add_lcov)
-      else:
-        self.ParseLcovFile(add_lcov)
-
-    for add_path in cfg.get('add_files', []):
-      if addfiles_queue is not None:
-        addfiles_queue.append(add_path)
-      else:
-        self.AddFiles(add_path)
-
-    self.print_stats += cfg.get('print_stats', [])
-
-  def ParseConfig(self, filename, **kwargs):
-    """Parses a configuration file.
-
-    Args:
-      filename: Config filename.
-      kwargs: Additional parameters to pass to AddConfig().
-    """
-    # TODO: All manner of error checking
-    f = None
-    try:
-      f = open(filename, 'rt')
-      # Need to strip CR's from CRLF-terminated lines or posix systems can't
-      # eval the data.
-      config_data = f.read().replace('\r\n', '\n')
-      # TODO: some sort of include syntax.
-      #
-      # Needs to be done at string-time rather than at eval()-time, so that
-      # it's possible to include parts of dicts.  Path from a file to its
-      # include should be relative to the dir containing the file.
-      #
-      # Or perhaps it could be done after eval.  In that case, there'd be an
-      # 'include' section with a list of files to include.  Those would be
-      # eval()'d and recursively pre- or post-merged with the including file.
-      #
-      # Or maybe just don't worry about it, since multiple configs can be
-      # specified on the command line.
-      self.AddConfig(config_data, **kwargs)
-    finally:
-      if f:
-        f.close()
-
-  def UpdateTreeStats(self):
-    """Recalculates the tree stats from the currently covered files.
-
-    Also calculates coverage summary for files.
-    """
-    self.tree = CoveredDir('')
-    for cov_file in self.files.itervalues():
-      # Add the file to the tree
-      fdirs = cov_file.filename.split('/')
-      parent = self.tree
-      ancestors = [parent]
-      for d in fdirs[:-1]:
-        if d not in parent.subdirs:
-          if parent.dirpath:
-            parent.subdirs[d] = CoveredDir(parent.dirpath + '/' + d)
-          else:
-            parent.subdirs[d] = CoveredDir(d)
-        parent = parent.subdirs[d]
-        ancestors.append(parent)
-      # Final subdir actually contains the file
-      parent.files[fdirs[-1]] = cov_file
-
-      # Now add file's contribution to coverage by dir
-      for a in ancestors:
-        # Add to 'all' group
-        a.stats_by_group['all'].Add(cov_file.stats)
-
-        # Add to group file belongs to
-        group = cov_file.attrs.get('group')
-        if group not in a.stats_by_group:
-          a.stats_by_group[group] = CoverageStats()
-        cbyg = a.stats_by_group[group]
-        cbyg.Add(cov_file.stats)
-
-  def PrintTree(self):
-    """Prints the tree stats."""
-    # Print the tree
-    print 'Lines of code coverage by directory:'
-    print self.tree.GetTree()
-
-#------------------------------------------------------------------------------
-
-
-def Main(argv):
-  """Main routine.
-
-  Args:
-    argv: list of arguments
-
-  Returns:
-    exit code, 0 for normal exit.
-  """
-  # Parse args
-  parser = optparse.OptionParser()
-  parser.add_option(
-      '-i', '--input', dest='inputs', type='string', action='append',
-      metavar='FILE',
-      help='read LCOV input from FILE')
-  parser.add_option(
-      '-r', '--root', dest='roots', type='string', action='append',
-      metavar='ROOT[=ALTNAME]',
-      help='add ROOT directory, optionally map in coverage results as ALTNAME')
-  parser.add_option(
-      '-c', '--config', dest='configs', type='string', action='append',
-      metavar='FILE',
-      help='read settings from configuration FILE')
-  parser.add_option(
-      '-a', '--addfiles', dest='addfiles', type='string', action='append',
-      metavar='PATH',
-      help='add files from PATH to coverage data')
-  parser.add_option(
-      '-t', '--tree', dest='tree', action='store_true',
-      help='print tree of code coverage by group')
-  parser.add_option(
-      '-u', '--uninstrumented', dest='uninstrumented', action='store_true',
-      help='list uninstrumented files')
-  parser.add_option(
-      '-m', '--html', dest='html_out', type='string', metavar='PATH',
-      help='write HTML output to PATH')
-  parser.add_option(
-      '-b', '--base_url', dest='base_url', type='string', metavar='URL',
-      help='include URL in base tag of HTML output')
-
-  parser.set_defaults(
-      inputs=[],
-      roots=[],
-      configs=[],
-      addfiles=[],
-      tree=False,
-      html_out=None,
-  )
-
-  options = parser.parse_args(args=argv)[0]
-
-  cov = Coverage()
-
-  # Set root directories for coverage
-  for root_opt in options.roots:
-    if '=' in root_opt:
-      cov.AddRoot(*root_opt.split('='))
-    else:
-      cov.AddRoot(root_opt)
-
-  # Read config files
-  for config_file in options.configs:
-    cov.ParseConfig(config_file, lcov_queue=options.inputs,
-                    addfiles_queue=options.addfiles)
-
-  # Parse lcov files
-  for input_filename in options.inputs:
-    cov.ParseLcovFile(input_filename)
-
-  # Add missing files
-  for add_path in options.addfiles:
-    cov.AddFiles(add_path)
-
-  # Print help if no files specified
-  if not cov.files:
-    print 'No covered files found.'
-    parser.print_help()
-    return 1
-
-  # Update tree stats
-  cov.UpdateTreeStats()
-
-  # Print uninstrumented filenames
-  if options.uninstrumented:
-    print 'Uninstrumented files:'
-    for f in sorted(cov.files):
-      covf = cov.files[f]
-      if not covf.in_lcov:
-        print '  %-6s %-6s %s' % (covf.attrs.get('group'),
-                                  covf.attrs.get('language'), f)
-
-  # Print tree stats
-  if options.tree:
-    cov.PrintTree()
-
-  # Print stats
-  for ps_args in cov.print_stats:
-    cov.PrintStat(**ps_args)
-
-  # Generate HTML
-  if options.html_out:
-    html = croc_html.CrocHtml(cov, options.html_out, options.base_url)
-    html.Write()
-
-  # Normal exit
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(Main(sys.argv))
diff --git a/tools/code_coverage/croc_html.py b/tools/code_coverage/croc_html.py
deleted file mode 100644
index 7866f472..0000000
--- a/tools/code_coverage/croc_html.py
+++ /dev/null
@@ -1,451 +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.
-
-"""Crocodile HTML output."""
-
-import os
-import shutil
-import time
-import xml.dom
-
-
-class CrocHtmlError(Exception):
-  """Coverage HTML error."""
-
-
-class HtmlElement(object):
-  """Node in a HTML file."""
-
-  def __init__(self, doc, element):
-    """Constructor.
-
-    Args:
-      doc: XML document object.
-      element: XML element.
-    """
-    self.doc = doc
-    self.element = element
-
-  def E(self, name, **kwargs):
-    """Adds a child element.
-
-    Args:
-      name: Name of element.
-      kwargs: Attributes for element.  To use an attribute which is a python
-          reserved word (i.e. 'class'), prefix the attribute name with 'e_'.
-
-    Returns:
-      The child element.
-    """
-    he = HtmlElement(self.doc, self.doc.createElement(name))
-    element = he.element
-    self.element.appendChild(element)
-
-    for k, v in kwargs.iteritems():
-      if k.startswith('e_'):
-        # Remove prefix
-        element.setAttribute(k[2:], str(v))
-      else:
-        element.setAttribute(k, str(v))
-
-    return he
-
-  def Text(self, text):
-    """Adds a text node.
-
-    Args:
-      text: Text to add.
-
-    Returns:
-      self.
-    """
-    t = self.doc.createTextNode(str(text))
-    self.element.appendChild(t)
-    return self
-
-
-class HtmlFile(object):
-  """HTML file."""
-
-  def __init__(self, xml_impl, filename):
-    """Constructor.
-
-    Args:
-      xml_impl: DOMImplementation to use to create document.
-      filename: Path to file.
-    """
-    self.xml_impl = xml_impl
-    doctype = xml_impl.createDocumentType(
-        'HTML', '-//W3C//DTD HTML 4.01//EN',
-        'http://www.w3.org/TR/html4/strict.dtd')
-    self.doc = xml_impl.createDocument(None, 'html', doctype)
-    self.filename = filename
-
-    # Create head and body elements
-    root = HtmlElement(self.doc, self.doc.documentElement)
-    self.head = root.E('head')
-    self.body = root.E('body')
-
-  def Write(self, cleanup=True):
-    """Writes the file.
-
-    Args:
-      cleanup: If True, calls unlink() on the internal xml document.  This
-          frees up memory, but means that you can't use this file for anything
-          else.
-    """
-    f = open(self.filename, 'wt')
-    self.doc.writexml(f, encoding='UTF-8')
-    f.close()
-
-    if cleanup:
-      self.doc.unlink()
-      # Prevent future uses of the doc now that we've unlinked it
-      self.doc = None
-
-#------------------------------------------------------------------------------
-
-COV_TYPE_STRING = {None: 'm', 0: 'i', 1: 'E', 2: ' '}
-COV_TYPE_CLASS = {None: 'missing', 0: 'instr', 1: 'covered', 2: ''}
-
-
-class CrocHtml(object):
-  """Crocodile HTML output class."""
-
-  def __init__(self, cov, output_root, base_url=None):
-    """Constructor."""
-    self.cov = cov
-    self.output_root = output_root
-    self.base_url = base_url
-    self.xml_impl = xml.dom.getDOMImplementation()
-    self.time_string = 'Coverage information generated %s.' % time.asctime()
-
-  def CreateHtmlDoc(self, filename, title):
-    """Creates a new HTML document.
-
-    Args:
-      filename: Filename to write to, relative to self.output_root.
-      title: Title of page
-
-    Returns:
-      The document.
-    """
-    f = HtmlFile(self.xml_impl, self.output_root + '/' + filename)
-
-    f.head.E('title').Text(title)
-
-    if self.base_url:
-      css_href = self.base_url + 'croc.css'
-      base_href = self.base_url + os.path.dirname(filename)
-      if not base_href.endswith('/'):
-        base_href += '/'
-      f.head.E('base', href=base_href)
-    else:
-      css_href = '../' * (len(filename.split('/')) - 1) + 'croc.css'
-
-    f.head.E('link', rel='stylesheet', type='text/css', href=css_href)
-
-    return f
-
-  def AddCaptionForFile(self, body, path):
-    """Adds a caption for the file, with links to each parent dir.
-
-    Args:
-      body: Body elemement.
-      path: Path to file.
-    """
-    # This is slightly different that for subdir, because it needs to have a
-    # link to the current directory's index.html.
-    hdr = body.E('h2')
-    hdr.Text('Coverage for ')
-    dirs = [''] + path.split('/')
-    num_dirs = len(dirs)
-    for i in range(num_dirs - 1):
-      hdr.E('a', href=(
-          '../' * (num_dirs - i - 2) + 'index.html')).Text(dirs[i] + '/')
-    hdr.Text(dirs[-1])
-
-  def AddCaptionForSubdir(self, body, path):
-    """Adds a caption for the subdir, with links to each parent dir.
-
-    Args:
-      body: Body elemement.
-      path: Path to subdir.
-    """
-    # Link to parent dirs
-    hdr = body.E('h2')
-    hdr.Text('Coverage for ')
-    dirs = [''] + path.split('/')
-    num_dirs = len(dirs)
-    for i in range(num_dirs - 1):
-      hdr.E('a', href=(
-          '../' * (num_dirs - i - 1) + 'index.html')).Text(dirs[i] + '/')
-    hdr.Text(dirs[-1] + '/')
-
-  def AddSectionHeader(self, table, caption, itemtype, is_file=False):
-    """Adds a section header to the coverage table.
-
-    Args:
-      table: Table to add rows to.
-      caption: Caption for section, if not None.
-      itemtype: Type of items in this section, if not None.
-      is_file: Are items in this section files?
-    """
-
-    if caption is not None:
-      table.E('tr').E('th', e_class='secdesc', colspan=8).Text(caption)
-
-    sec_hdr = table.E('tr')
-
-    if itemtype is not None:
-      sec_hdr.E('th', e_class='section').Text(itemtype)
-
-    sec_hdr.E('th', e_class='section').Text('Coverage')
-    sec_hdr.E('th', e_class='section', colspan=3).Text(
-        'Lines executed / instrumented / missing')
-
-    graph = sec_hdr.E('th', e_class='section')
-    graph.E('span', style='color:#00FF00').Text('exe')
-    graph.Text(' / ')
-    graph.E('span', style='color:#FFFF00').Text('inst')
-    graph.Text(' / ')
-    graph.E('span', style='color:#FF0000').Text('miss')
-
-    if is_file:
-      sec_hdr.E('th', e_class='section').Text('Language')
-      sec_hdr.E('th', e_class='section').Text('Group')
-    else:
-      sec_hdr.E('th', e_class='section', colspan=2)
-
-  def AddItem(self, table, itemname, stats, attrs, link=None):
-    """Adds a bar graph to the element.  This is a series of <td> elements.
-
-    Args:
-      table: Table to add item to.
-      itemname: Name of item.
-      stats: Stats object.
-      attrs: Attributes dictionary; if None, no attributes will be printed.
-      link: Destination for itemname hyperlink, if not None.
-    """
-    row = table.E('tr')
-
-    # Add item name
-    if itemname is not None:
-      item_elem = row.E('td')
-      if link is not None:
-        item_elem = item_elem.E('a', href=link)
-      item_elem.Text(itemname)
-
-    # Get stats
-    stat_exe = stats.get('lines_executable', 0)
-    stat_ins = stats.get('lines_instrumented', 0)
-    stat_cov = stats.get('lines_covered', 0)
-
-    percent = row.E('td')
-
-    # Add text
-    row.E('td', e_class='number').Text(stat_cov)
-    row.E('td', e_class='number').Text(stat_ins)
-    row.E('td', e_class='number').Text(stat_exe - stat_ins)
-
-    # Add percent and graph; only fill in if there's something in there
-    graph = row.E('td', e_class='graph', width=100)
-    if stat_exe:
-      percent_cov = 100.0 * stat_cov / stat_exe
-      percent_ins = 100.0 * stat_ins / stat_exe
-
-      # Color percent based on thresholds
-      percent.Text('%.1f%%' % percent_cov)
-      if percent_cov >= 80:
-        percent.element.setAttribute('class', 'high_pct')
-      elif percent_cov >= 60:
-        percent.element.setAttribute('class', 'mid_pct')
-      else:
-        percent.element.setAttribute('class', 'low_pct')
-
-      # Graphs use integer values
-      percent_cov = int(percent_cov)
-      percent_ins = int(percent_ins)
-
-      graph.Text('.')
-      graph.E('span', style='padding-left:%dpx' % percent_cov,
-              e_class='g_covered')
-      graph.E('span', style='padding-left:%dpx' % (percent_ins - percent_cov),
-              e_class='g_instr')
-      graph.E('span', style='padding-left:%dpx' % (100 - percent_ins),
-              e_class='g_missing')
-
-    if attrs:
-      row.E('td', e_class='stat').Text(attrs.get('language'))
-      row.E('td', e_class='stat').Text(attrs.get('group'))
-    else:
-      row.E('td', colspan=2)
-
-  def WriteFile(self, cov_file):
-    """Writes the HTML for a file.
-
-    Args:
-      cov_file: croc.CoveredFile to write.
-    """
-    print '  ' + cov_file.filename
-    title = 'Coverage for ' + cov_file.filename
-
-    f = self.CreateHtmlDoc(cov_file.filename + '.html', title)
-    body = f.body
-
-    # Write header section
-    self.AddCaptionForFile(body, cov_file.filename)
-
-    # Summary for this file
-    table = body.E('table')
-    self.AddSectionHeader(table, None, None, is_file=True)
-    self.AddItem(table, None, cov_file.stats, cov_file.attrs)
-
-    body.E('h2').Text('Line-by-line coverage:')
-
-    # Print line-by-line coverage
-    if cov_file.local_path:
-      code_table = body.E('table').E('tr').E('td').E('pre')
-
-      flines = open(cov_file.local_path, 'rt')
-      lineno = 0
-
-      for line in flines:
-        lineno += 1
-        line_cov = cov_file.lines.get(lineno, 2)
-        e_class = COV_TYPE_CLASS.get(line_cov)
-
-        code_table.E('span', e_class=e_class).Text('%4d  %s :  %s\n' % (
-            lineno,
-            COV_TYPE_STRING.get(line_cov),
-            line.rstrip()
-        ))
-
-    else:
-      body.Text('Line-by-line coverage not available.  Make sure the directory'
-                ' containing this file has been scanned via ')
-      body.E('B').Text('add_files')
-      body.Text(' in a configuration file, or the ')
-      body.E('B').Text('--addfiles')
-      body.Text(' command line option.')
-
-      # TODO: if file doesn't have a local path, try to find it by
-      # reverse-mapping roots and searching for the file.
-
-    body.E('p', e_class='time').Text(self.time_string)
-    f.Write()
-
-  def WriteSubdir(self, cov_dir):
-    """Writes the index.html for a subdirectory.
-
-    Args:
-      cov_dir: croc.CoveredDir to write.
-    """
-    print '  ' + cov_dir.dirpath + '/'
-
-    # Create the subdir if it doesn't already exist
-    subdir = self.output_root + '/' + cov_dir.dirpath
-    if not os.path.exists(subdir):
-      os.mkdir(subdir)
-
-    if cov_dir.dirpath:
-      title = 'Coverage for ' + cov_dir.dirpath + '/'
-      f = self.CreateHtmlDoc(cov_dir.dirpath + '/index.html', title)
-    else:
-      title = 'Coverage summary'
-      f = self.CreateHtmlDoc('index.html', title)
-
-    body = f.body
-
-    dirs = [''] + cov_dir.dirpath.split('/')
-    num_dirs = len(dirs)
-    sort_jsfile = '../' * (num_dirs - 1) + 'sorttable.js'
-    script = body.E('script', src=sort_jsfile)
-    body.E('/script')
-
-    # Write header section
-    if cov_dir.dirpath:
-      self.AddCaptionForSubdir(body, cov_dir.dirpath)
-    else:
-      body.E('h2').Text(title)
-
-    table = body.E('table', e_class='sortable')
-    table.E('h3').Text('Coverage by Group')
-    # Coverage by group
-    self.AddSectionHeader(table, None, 'Group')
-
-    for group in sorted(cov_dir.stats_by_group):
-      self.AddItem(table, group, cov_dir.stats_by_group[group], None)
-
-    # List subdirs
-    if cov_dir.subdirs:
-      table = body.E('table', e_class='sortable')
-      table.E('h3').Text('Subdirectories')
-      self.AddSectionHeader(table, None, 'Subdirectory')
-
-      for d in sorted(cov_dir.subdirs):
-        self.AddItem(table, d + '/', cov_dir.subdirs[d].stats_by_group['all'],
-                     None, link=d + '/index.html')
-
-    # List files
-    if cov_dir.files:
-      table = body.E('table', e_class='sortable')
-      table.E('h3').Text('Files in This Directory')
-      self.AddSectionHeader(table, None, 'Filename',
-                            is_file=True)
-
-      for filename in sorted(cov_dir.files):
-        cov_file = cov_dir.files[filename]
-        self.AddItem(table, filename, cov_file.stats, cov_file.attrs,
-                     link=filename + '.html')
-
-    body.E('p', e_class='time').Text(self.time_string)
-    f.Write()
-
-  def WriteRoot(self):
-    """Writes the files in the output root."""
-    # Find ourselves
-    src_dir = os.path.split(self.WriteRoot.func_code.co_filename)[0]
-
-    # Files to copy into output root
-    copy_files = ['croc.css']
-    # Third_party files to copy into output root
-    third_party_files = ['sorttable.js']
-
-    # Copy files from our directory into the output directory
-    for copy_file in copy_files:
-      print '  Copying %s' % copy_file
-      shutil.copyfile(os.path.join(src_dir, copy_file),
-                      os.path.join(self.output_root, copy_file))
-    # Copy third party files from third_party directory into
-    # the output directory
-    src_dir = os.path.join(src_dir, 'third_party')
-    for third_party_file in third_party_files:
-      print '  Copying %s' % third_party_file
-      shutil.copyfile(os.path.join(src_dir, third_party_file),
-                      os.path.join(self.output_root, third_party_file))
-
-  def Write(self):
-    """Writes HTML output."""
-
-    print 'Writing HTML to %s...' % self.output_root
-
-    # Loop through the tree and write subdirs, breadth-first
-    # TODO: switch to depth-first and sort values - makes nicer output?
-    todo = [self.cov.tree]
-    while todo:
-      cov_dir = todo.pop(0)
-
-      # Append subdirs to todo list
-      todo += cov_dir.subdirs.values()
-
-      # Write this subdir
-      self.WriteSubdir(cov_dir)
-
-      # Write files in this subdir
-      for cov_file in cov_dir.files.itervalues():
-        self.WriteFile(cov_file)
-
-    # Write files in root directory
-    self.WriteRoot()
diff --git a/tools/code_coverage/croc_scan.py b/tools/code_coverage/croc_scan.py
deleted file mode 100644
index 8d0e2e8d..0000000
--- a/tools/code_coverage/croc_scan.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Crocodile source scanners."""
-
-
-import re
-
-
-class Scanner(object):
-  """Generic source scanner."""
-
-  def __init__(self):
-    """Constructor."""
-
-    self.re_token = re.compile('#')
-    self.comment_to_eol = ['#']
-    self.comment_start = None
-    self.comment_end = None
-
-  def ScanLines(self, lines):
-    """Scans the lines for executable statements.
-
-    Args:
-      lines: Iterator returning source lines.
-
-    Returns:
-      An array of line numbers which are executable.
-    """
-    exe_lines = []
-    lineno = 0
-
-    in_string = None
-    in_comment = None
-    comment_index = None
-
-    for line in lines:
-      lineno += 1
-      in_string_at_start = in_string
-
-      for t in self.re_token.finditer(line):
-        tokenstr = t.groups()[0]
-
-        if in_comment:
-          # Inside a multi-line comment, so look for end token
-          if tokenstr == in_comment:
-            in_comment = None
-            # Replace comment with spaces
-            line = (line[:comment_index]
-                    + ' ' * (t.end(0) - comment_index)
-                    + line[t.end(0):])
-
-        elif in_string:
-          # Inside a string, so look for end token
-          if tokenstr == in_string:
-            in_string = None
-
-        elif tokenstr in self.comment_to_eol:
-          # Single-line comment, so truncate line at start of token
-          line = line[:t.start(0)]
-          break
-
-        elif tokenstr == self.comment_start:
-          # Multi-line comment start - end token is comment_end
-          in_comment = self.comment_end
-          comment_index = t.start(0)
-
-        else:
-          # Starting a string - end token is same as start
-          in_string = tokenstr
-
-      # If still in comment at end of line, remove comment
-      if in_comment:
-        line = line[:comment_index]
-        # Next line, delete from the beginnine
-        comment_index = 0
-
-      # If line-sans-comments is not empty, claim it may be executable
-      if line.strip() or in_string_at_start:
-        exe_lines.append(lineno)
-
-    # Return executable lines
-    return exe_lines
-
-  def Scan(self, filename):
-    """Reads the file and scans its lines.
-
-    Args:
-      filename: Path to file to scan.
-
-    Returns:
-      An array of line numbers which are executable.
-    """
-
-    # TODO: All manner of error checking
-    f = None
-    try:
-      f = open(filename, 'rt')
-      return self.ScanLines(f)
-    finally:
-      if f:
-        f.close()
-
-
-class PythonScanner(Scanner):
-  """Python source scanner."""
-
-  def __init__(self):
-    """Constructor."""
-    Scanner.__init__(self)
-
-    # TODO: This breaks for strings ending in more than 2 backslashes.  Need
-    # a pattern which counts only an odd number of backslashes, so the last
-    # one thus escapes the quote.
-    self.re_token = re.compile(r'(#|\'\'\'|"""|(?<!(?<!\\)\\)["\'])')
-    self.comment_to_eol = ['#']
-    self.comment_start = None
-    self.comment_end = None
-
-
-class CppScanner(Scanner):
-  """C / C++ / ObjC / ObjC++ source scanner."""
-
-  def __init__(self):
-    """Constructor."""
-    Scanner.__init__(self)
-
-    # TODO: This breaks for strings ending in more than 2 backslashes.  Need
-    # a pattern which counts only an odd number of backslashes, so the last
-    # one thus escapes the quote.
-    self.re_token = re.compile(r'(^\s*#|//|/\*|\*/|(?<!(?<!\\)\\)["\'])')
-
-    # TODO: Treat '\' at EOL as a token, and handle it as continuing the
-    # previous line.  That is, if in a comment-to-eol, this line is a comment
-    # too.
-
-    # Note that we treat # at beginning of line as a comment, so that we ignore
-    # preprocessor definitions
-    self.comment_to_eol = ['//', '#']
-
-    self.comment_start = '/*'
-    self.comment_end = '*/'
-
-
-def ScanFile(filename, language):
-  """Scans a file for executable lines.
-
-  Args:
-    filename: Path to file to scan.
-    language: Language for file ('C', 'C++', 'python', 'ObjC', 'ObjC++')
-
-  Returns:
-    A list of executable lines, or an empty list if the file was not a handled
-        language.
-  """
-
-  if language == 'python':
-    return PythonScanner().Scan(filename)
-  elif language in ['C', 'C++', 'ObjC', 'ObjC++']:
-    return CppScanner().Scan(filename)
-
-  # Something we don't handle
-  return []
diff --git a/tools/code_coverage/croc_scan_test.py b/tools/code_coverage/croc_scan_test.py
deleted file mode 100755
index a69b28a..0000000
--- a/tools/code_coverage/croc_scan_test.py
+++ /dev/null
@@ -1,187 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Unit tests for croc_scan.py."""
-
-import re
-import unittest
-import croc_scan
-
-
-class TestScanner(unittest.TestCase):
-  """Tests for croc_scan.Scanner."""
-
-  def testInit(self):
-    """Test __init()__."""
-    s = croc_scan.Scanner()
-
-    self.assertEqual(s.re_token.pattern, '#')
-    self.assertEqual(s.comment_to_eol, ['#'])
-    self.assertEqual(s.comment_start, None)
-    self.assertEqual(s.comment_end, None)
-
-  def testScanLines(self):
-    """Test ScanLines()."""
-    s = croc_scan.Scanner()
-    # Set up imaginary language:
-    #   ':' = comment to EOL
-    #   '"' = string start/end
-    #   '(' = comment start
-    #   ')' = comment end
-    s.re_token = re.compile(r'([\:\"\(\)])')
-    s.comment_to_eol = [':']
-    s.comment_start = '('
-    s.comment_end = ')'
-
-    # No input file = no output lines
-    self.assertEqual(s.ScanLines([]), [])
-
-    # Empty lines and lines with only whitespace are ignored
-    self.assertEqual(s.ScanLines([
-        '',             # 1
-        'line',         # 2 exe
-        ' \t  ',        # 3
-    ]), [2])
-
-    # Comments to EOL are stripped, but not inside strings
-    self.assertEqual(s.ScanLines([
-        'test',                                                 # 1 exe
-        '   : A comment',                                       # 2
-        '"a : in a string"',                                    # 3 exe
-        'test2 : with comment to EOL',                          # 4 exe
-        'foo = "a multiline string with an empty line',         # 5 exe
-        '',                                                     # 6 exe
-        ': and a comment-to-EOL character"',                    # 7 exe
-        ': done',                                               # 8
-    ]), [1, 3, 4, 5, 6, 7])
-
-    # Test Comment start/stop detection
-    self.assertEqual(s.ScanLines([
-        '( a comment on one line)',                     # 1
-        'text (with a comment)',                        # 2 exe
-        '( a comment with a : in the middle)',          # 3
-        '( a multi-line',                               # 4
-        '  comment)',                                   # 5
-        'a string "with a ( in it"',                    # 6 exe
-        'not in a multi-line comment',                  # 7 exe
-        '(a comment with a " in it)',                   # 8
-        ': not in a string, so this gets stripped',     # 9
-        'more text "with an uninteresting string"',     # 10 exe
-    ]), [2, 6, 7, 10])
-
-  # TODO: Test Scan().  Low priority, since it just wraps ScanLines().
-
-
-class TestPythonScanner(unittest.TestCase):
-  """Tests for croc_scan.PythonScanner."""
-
-  def testScanLines(self):
-    """Test ScanLines()."""
-    s = croc_scan.PythonScanner()
-
-    # No input file = no output lines
-    self.assertEqual(s.ScanLines([]), [])
-
-    self.assertEqual(s.ScanLines([
-        '# a comment',                                  # 1
-        '',                                             # 2
-        '"""multi-line string',                         # 3 exe
-        '# not a comment',                              # 4 exe
-        'end of multi-line string"""',                  # 5 exe
-        '  ',                                           # 6
-        '"single string with #comment"',                # 7 exe
-        '',                                             # 8
-        '\'\'\'multi-line string, single-quote',        # 9 exe
-        '# not a comment',                              # 10 exe
-        'end of multi-line string\'\'\'',               # 11 exe
-        '',                                             # 12
-        '"string with embedded \\" is handled"',        # 13 exe
-        '# quoted "',                                   # 14
-        '"\\""',                                        # 15 exe
-        '# quoted backslash',                           # 16
-        '"\\\\"',                                       # 17 exe
-        'main()',                                       # 18 exe
-        '# end',                                        # 19
-    ]), [3, 4, 5, 7, 9, 10, 11, 13, 15, 17, 18])
-
-
-class TestCppScanner(unittest.TestCase):
-  """Tests for croc_scan.CppScanner."""
-
-  def testScanLines(self):
-    """Test ScanLines()."""
-    s = croc_scan.CppScanner()
-
-    # No input file = no output lines
-    self.assertEqual(s.ScanLines([]), [])
-
-    self.assertEqual(s.ScanLines([
-        '// a comment',                                 # 1
-        '# a preprocessor define',                      # 2
-        '',                                             # 3
-        '\'#\', \'"\'',                                 # 4 exe
-        '',                                             # 5
-        '/* a multi-line comment',                      # 6
-        'with a " in it',                               # 7
-        '*/',                                           # 8
-        '',                                             # 9
-        '"a string with /* and \' in it"',              # 10 exe
-        '',                                             # 11
-        '"a multi-line string\\',                       # 12 exe
-        '// not a comment\\',                           # 13 exe
-        'ending here"',                                 # 14 exe
-        '',                                             # 15
-        '"string with embedded \\" is handled"',        # 16 exe
-        '',                                             # 17
-        'main()',                                       # 18 exe
-        '// end',                                       # 19
-    ]), [4, 10, 12, 13, 14, 16, 18])
-
-
-class TestScanFile(unittest.TestCase):
-  """Tests for croc_scan.ScanFile()."""
-
-  class MockScanner(object):
-    """Mock scanner."""
-
-    def __init__(self, language):
-      """Constructor."""
-      self.language = language
-
-    def Scan(self, filename):
-      """Mock Scan() method."""
-      return 'scan %s %s' % (self.language, filename)
-
-  def MockPythonScanner(self):
-    return self.MockScanner('py')
-
-  def MockCppScanner(self):
-    return self.MockScanner('cpp')
-
-  def setUp(self):
-    """Per-test setup."""
-    # Hook scanners
-    self.old_python_scanner = croc_scan.PythonScanner
-    self.old_cpp_scanner = croc_scan.CppScanner
-    croc_scan.PythonScanner = self.MockPythonScanner
-    croc_scan.CppScanner = self.MockCppScanner
-
-  def tearDown(self):
-    """Per-test cleanup."""
-    croc_scan.PythonScanner = self.old_python_scanner
-    croc_scan.CppScanner = self.old_cpp_scanner
-
-  def testScanFile(self):
-    """Test ScanFile()."""
-    self.assertEqual(croc_scan.ScanFile('foo', 'python'), 'scan py foo')
-    self.assertEqual(croc_scan.ScanFile('bar1', 'C'), 'scan cpp bar1')
-    self.assertEqual(croc_scan.ScanFile('bar2', 'C++'), 'scan cpp bar2')
-    self.assertEqual(croc_scan.ScanFile('bar3', 'ObjC'), 'scan cpp bar3')
-    self.assertEqual(croc_scan.ScanFile('bar4', 'ObjC++'), 'scan cpp bar4')
-    self.assertEqual(croc_scan.ScanFile('bar', 'fortran'), [])
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/tools/code_coverage/croc_test.py b/tools/code_coverage/croc_test.py
deleted file mode 100755
index 7c2521c..0000000
--- a/tools/code_coverage/croc_test.py
+++ /dev/null
@@ -1,758 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Unit tests for Crocodile."""
-
-import os
-import StringIO
-import unittest
-import croc
-
-
-class TestCoverageStats(unittest.TestCase):
-  """Tests for croc.CoverageStats."""
-
-  def testAdd(self):
-    """Test Add()."""
-    c = croc.CoverageStats()
-
-    # Initially empty
-    self.assertEqual(c, {})
-
-    # Add items
-    c['a'] = 1
-    c['b'] = 0
-    self.assertEqual(c, {'a': 1, 'b': 0})
-
-    # Add dict with non-overlapping items
-    c.Add({'c': 5})
-    self.assertEqual(c, {'a': 1, 'b': 0, 'c': 5})
-
-    # Add dict with overlapping items
-    c.Add({'a': 4, 'd': 3})
-    self.assertEqual(c, {'a': 5, 'b': 0, 'c': 5, 'd': 3})
-
-
-class TestCoveredFile(unittest.TestCase):
-  """Tests for croc.CoveredFile."""
-
-  def setUp(self):
-    self.cov_file = croc.CoveredFile('bob.cc', group='source', language='C++')
-
-  def testInit(self):
-    """Test init."""
-    f = self.cov_file
-
-    # Check initial values
-    self.assertEqual(f.filename, 'bob.cc')
-    self.assertEqual(f.attrs, {'group': 'source', 'language': 'C++'})
-    self.assertEqual(f.lines, {})
-    self.assertEqual(f.stats, {})
-    self.assertEqual(f.local_path, None)
-    self.assertEqual(f.in_lcov, False)
-
-  def testUpdateCoverageEmpty(self):
-    """Test updating coverage when empty."""
-    f = self.cov_file
-    f.UpdateCoverage()
-    self.assertEqual(f.stats, {
-        'lines_executable': 0,
-        'lines_instrumented': 0,
-        'lines_covered': 0,
-        'files_executable': 1,
-    })
-
-  def testUpdateCoverageExeOnly(self):
-    """Test updating coverage when no lines are instrumented."""
-    f = self.cov_file
-    f.lines = {1: None, 2: None, 4: None}
-    f.UpdateCoverage()
-    self.assertEqual(f.stats, {
-        'lines_executable': 3,
-        'lines_instrumented': 0,
-        'lines_covered': 0,
-        'files_executable': 1,
-    })
-
-    # Now mark the file instrumented via in_lcov
-    f.in_lcov = True
-    f.UpdateCoverage()
-    self.assertEqual(f.stats, {
-        'lines_executable': 3,
-        'lines_instrumented': 0,
-        'lines_covered': 0,
-        'files_executable': 1,
-        'files_instrumented': 1,
-    })
-
-  def testUpdateCoverageExeAndInstr(self):
-    """Test updating coverage when no lines are covered."""
-    f = self.cov_file
-    f.lines = {1: None, 2: None, 4: 0, 5: 0, 7: None}
-    f.UpdateCoverage()
-    self.assertEqual(f.stats, {
-        'lines_executable': 5,
-        'lines_instrumented': 2,
-        'lines_covered': 0,
-        'files_executable': 1,
-        'files_instrumented': 1,
-    })
-
-  def testUpdateCoverageWhenCovered(self):
-    """Test updating coverage when lines are covered."""
-    f = self.cov_file
-    f.lines = {1: None, 2: None, 3: 1, 4: 0, 5: 0, 6: 1, 7: None}
-    f.UpdateCoverage()
-    self.assertEqual(f.stats, {
-        'lines_executable': 7,
-        'lines_instrumented': 4,
-        'lines_covered': 2,
-        'files_executable': 1,
-        'files_instrumented': 1,
-        'files_covered': 1,
-    })
-
-
-class TestCoveredDir(unittest.TestCase):
-  """Tests for croc.CoveredDir."""
-
-  def setUp(self):
-    self.cov_dir = croc.CoveredDir('/a/b/c')
-
-  def testInit(self):
-    """Test init."""
-    d = self.cov_dir
-
-    # Check initial values
-    self.assertEqual(d.dirpath, '/a/b/c')
-    self.assertEqual(d.files, {})
-    self.assertEqual(d.subdirs, {})
-    self.assertEqual(d.stats_by_group, {'all': {}})
-
-  def testGetTreeEmpty(self):
-    """Test getting empty tree."""
-    d = self.cov_dir
-    self.assertEqual(d.GetTree(), 'c/')
-
-  def testGetTreeStats(self):
-    """Test getting tree with stats."""
-    d = self.cov_dir
-    d.stats_by_group['all'] = croc.CoverageStats(
-        lines_executable=50, lines_instrumented=30, lines_covered=20)
-    d.stats_by_group['bar'] = croc.CoverageStats(
-        lines_executable=0, lines_instrumented=0, lines_covered=0)
-    d.stats_by_group['foo'] = croc.CoverageStats(
-        lines_executable=33, lines_instrumented=22, lines_covered=11)
-    # 'bar' group is skipped because it has no executable lines
-    self.assertEqual(
-        d.GetTree(),
-        'c/                               all:20/30/50   foo:11/22/33')
-
-  def testGetTreeSubdir(self):
-    """Test getting tree with subdirs."""
-    d1 = self.cov_dir = croc.CoveredDir('/a')
-    d2 = self.cov_dir = croc.CoveredDir('/a/b')
-    d3 = self.cov_dir = croc.CoveredDir('/a/c')
-    d4 = self.cov_dir = croc.CoveredDir('/a/b/d')
-    d5 = self.cov_dir = croc.CoveredDir('/a/b/e')
-    d1.subdirs = {'/a/b': d2, '/a/c': d3}
-    d2.subdirs = {'/a/b/d': d4, '/a/b/e': d5}
-    self.assertEqual(d1.GetTree(), 'a/\n  b/\n    d/\n    e/\n  c/')
-
-
-class TestCoverage(unittest.TestCase):
-  """Tests for croc.Coverage."""
-
-  def MockWalk(self, src_dir):
-    """Mock for os.walk().
-
-    Args:
-      src_dir: Source directory to walk.
-
-    Returns:
-      A list of (dirpath, dirnames, filenames) tuples.
-    """
-    self.mock_walk_calls.append(src_dir)
-    return self.mock_walk_return
-
-  def MockScanFile(self, filename, language):
-    """Mock for croc_scan.ScanFile().
-
-    Args:
-      filename: Path to file to scan.
-      language: Language for file.
-
-    Returns:
-      A list of executable lines.
-    """
-    self.mock_scan_calls.append([filename, language])
-    if filename in self.mock_scan_return:
-      return self.mock_scan_return[filename]
-    else:
-      return self.mock_scan_return['default']
-
-  def setUp(self):
-    """Per-test setup."""
-
-    # Empty coverage object
-    self.cov = croc.Coverage()
-
-    # Coverage object with minimal setup
-    self.cov_minimal = croc.Coverage()
-    self.cov_minimal.AddRoot('/src')
-    self.cov_minimal.AddRoot('c:\\source')
-    self.cov_minimal.AddRule('^_/', include=1, group='my')
-    self.cov_minimal.AddRule('.*\\.c$', language='C')
-    self.cov_minimal.AddRule('.*\\.c##$', language='C##')  # sharper than thou
-
-    # Data for MockWalk()
-    self.mock_walk_calls = []
-    self.mock_walk_return = []
-
-    # Data for MockScanFile()
-    self.mock_scan_calls = []
-    self.mock_scan_return = {'default': [1]}
-
-  def testInit(self):
-    """Test init."""
-    c = self.cov
-    self.assertEqual(c.files, {})
-    self.assertEqual(c.root_dirs, [])
-    self.assertEqual(c.print_stats, [])
-    self.assertEqual(c.rules, [])
-
-  def testAddRoot(self):
-    """Test AddRoot() and CleanupFilename()."""
-    c = self.cov
-
-    # Check for identity on already-clean filenames
-    self.assertEqual(c.CleanupFilename(''), '')
-    self.assertEqual(c.CleanupFilename('a'), 'a')
-    self.assertEqual(c.CleanupFilename('.a'), '.a')
-    self.assertEqual(c.CleanupFilename('..a'), '..a')
-    self.assertEqual(c.CleanupFilename('a.b'), 'a.b')
-    self.assertEqual(c.CleanupFilename('a/b/c'), 'a/b/c')
-    self.assertEqual(c.CleanupFilename('a/b/c/'), 'a/b/c/')
-
-    # Backslash to forward slash
-    self.assertEqual(c.CleanupFilename('a\\b\\c'), 'a/b/c')
-
-    # Handle relative paths
-    self.assertEqual(c.CleanupFilename('.'),
-                     c.CleanupFilename(os.path.abspath('.')))
-    self.assertEqual(c.CleanupFilename('..'),
-                     c.CleanupFilename(os.path.abspath('..')))
-    self.assertEqual(c.CleanupFilename('./foo/bar'),
-                     c.CleanupFilename(os.path.abspath('./foo/bar')))
-    self.assertEqual(c.CleanupFilename('../../a/b/c'),
-                     c.CleanupFilename(os.path.abspath('../../a/b/c')))
-
-    # Replace alt roots
-    c.AddRoot('foo')
-    self.assertEqual(c.CleanupFilename('foo'), '_')
-    self.assertEqual(c.CleanupFilename('foo/bar/baz'), '_/bar/baz')
-    self.assertEqual(c.CleanupFilename('aaa/foo'), 'aaa/foo')
-
-    # Alt root replacement is applied for all roots
-    c.AddRoot('foo/bar', '_B')
-    self.assertEqual(c.CleanupFilename('foo/bar/baz'), '_B/baz')
-
-    # Can use previously defined roots in cleanup
-    c.AddRoot('_/nom/nom/nom', '_CANHAS')
-    self.assertEqual(c.CleanupFilename('foo/nom/nom/nom/cheezburger'),
-                     '_CANHAS/cheezburger')
-
-    # Verify roots starting with UNC paths or drive letters work, and that
-    # more than one root can point to the same alt_name
-    c.AddRoot('/usr/local/foo', '_FOO')
-    c.AddRoot('D:\\my\\foo', '_FOO')
-    self.assertEqual(c.CleanupFilename('/usr/local/foo/a/b'), '_FOO/a/b')
-    self.assertEqual(c.CleanupFilename('D:\\my\\foo\\c\\d'), '_FOO/c/d')
-
-    # Cannot specify a blank alt_name
-    self.assertRaises(ValueError, c.AddRoot, 'some_dir', '')
-
-  def testAddRule(self):
-    """Test AddRule() and ClassifyFile()."""
-    c = self.cov
-
-    # With only the default rule, nothing gets kept
-    self.assertEqual(c.ClassifyFile('_/src/'), {})
-    self.assertEqual(c.ClassifyFile('_/src/a.c'), {})
-
-    # Add rules to include a tree and set a default group
-    c.AddRule('^_/src/', include=1, group='source')
-    self.assertEqual(c.ClassifyFile('_/src/'),
-                     {'include': 1, 'group': 'source'})
-    self.assertEqual(c.ClassifyFile('_/notsrc/'), {})
-    self.assertEqual(c.ClassifyFile('_/src/a.c'),
-                     {'include': 1, 'group': 'source'})
-
-    # Define some languages and groups
-    c.AddRule('.*\\.(c|h)$', language='C')
-    c.AddRule('.*\\.py$', language='Python')
-    c.AddRule('.*_test\\.', group='test')
-    self.assertEqual(c.ClassifyFile('_/src/a.c'),
-                     {'include': 1, 'group': 'source', 'language': 'C'})
-    self.assertEqual(c.ClassifyFile('_/src/a.h'),
-                     {'include': 1, 'group': 'source', 'language': 'C'})
-    self.assertEqual(c.ClassifyFile('_/src/a.cpp'),
-                     {'include': 1, 'group': 'source'})
-    self.assertEqual(c.ClassifyFile('_/src/a_test.c'),
-                     {'include': 1, 'group': 'test', 'language': 'C'})
-    self.assertEqual(c.ClassifyFile('_/src/test_a.c'),
-                     {'include': 1, 'group': 'source', 'language': 'C'})
-    self.assertEqual(c.ClassifyFile('_/src/foo/bar.py'),
-                     {'include': 1, 'group': 'source', 'language': 'Python'})
-    self.assertEqual(c.ClassifyFile('_/src/test.py'),
-                     {'include': 1, 'group': 'source', 'language': 'Python'})
-
-    # Exclude a path (for example, anything in a build output dir)
-    c.AddRule('.*/build/', include=0)
-    # But add back in a dir which matched the above rule but isn't a build
-    # output dir
-    c.AddRule('_/src/tools/build/', include=1)
-    self.assertEqual(c.ClassifyFile('_/src/build.c').get('include'), 1)
-    self.assertEqual(c.ClassifyFile('_/src/build/').get('include'), 0)
-    self.assertEqual(c.ClassifyFile('_/src/build/a.c').get('include'), 0)
-    self.assertEqual(c.ClassifyFile('_/src/tools/build/').get('include'), 1)
-    self.assertEqual(c.ClassifyFile('_/src/tools/build/t.c').get('include'), 1)
-
-  def testGetCoveredFile(self):
-    """Test GetCoveredFile()."""
-    c = self.cov_minimal
-
-    # Not currently any covered files
-    self.assertEqual(c.GetCoveredFile('_/a.c'), None)
-
-    # Add some files
-    a_c = c.GetCoveredFile('_/a.c', add=True)
-    b_c = c.GetCoveredFile('_/b.c##', add=True)
-    self.assertEqual(a_c.filename, '_/a.c')
-    self.assertEqual(a_c.attrs, {'include': 1, 'group': 'my', 'language': 'C'})
-    self.assertEqual(b_c.filename, '_/b.c##')
-    self.assertEqual(b_c.attrs,
-                     {'include': 1, 'group': 'my', 'language': 'C##'})
-
-    # Specifying the same filename should return the existing object
-    self.assertEqual(c.GetCoveredFile('_/a.c'), a_c)
-    self.assertEqual(c.GetCoveredFile('_/a.c', add=True), a_c)
-
-    # Filenames get cleaned on the way in, as do root paths
-    self.assertEqual(c.GetCoveredFile('/src/a.c'), a_c)
-    self.assertEqual(c.GetCoveredFile('c:\\source\\a.c'), a_c)
-
-    # TODO: Make sure that covered files require language, group, and include
-    # (since that checking is now done in GetCoveredFile() rather than
-    # ClassifyFile())
-
-  def testRemoveCoveredFile(self):
-    """Test RemoveCoveredFile()."""
-    # TODO: TEST ME!
-
-  def testParseLcov(self):
-    """Test ParseLcovData()."""
-    c = self.cov_minimal
-
-    c.ParseLcovData([
-        '# Ignore unknown lines',
-        # File we should include'
-        'SF:/src/a.c',
-        'DA:10,1',
-        'DA:11,0',
-        'DA:12,1   \n',  # Trailing whitespace should get stripped
-        'end_of_record',
-        # File we should ignore
-        'SF:/not_src/a.c',
-        'DA:20,1',
-        'end_of_record',
-        # Same as first source file, but alternate root
-        'SF:c:\\source\\a.c',
-        'DA:30,1',
-        'end_of_record',
-        # Ignore extra end of record
-        'end_of_record',
-        # Ignore data points after end of record
-        'DA:40,1',
-        # Instrumented but uncovered file
-        'SF:/src/b.c',
-        'DA:50,0',
-        'end_of_record',
-        # Empty file (instrumented but no executable lines)
-        'SF:c:\\source\\c.c',
-        'end_of_record',
-    ])
-
-    # We should know about three files
-    self.assertEqual(sorted(c.files), ['_/a.c', '_/b.c', '_/c.c'])
-
-    # Check expected contents
-    a_c = c.GetCoveredFile('_/a.c')
-    self.assertEqual(a_c.lines, {10: 1, 11: 0, 12: 1, 30: 1})
-    self.assertEqual(a_c.stats, {
-        'files_executable': 1,
-        'files_instrumented': 1,
-        'files_covered': 1,
-        'lines_instrumented': 4,
-        'lines_executable': 4,
-        'lines_covered': 3,
-    })
-    self.assertEqual(a_c.in_lcov, True)
-
-    b_c = c.GetCoveredFile('_/b.c')
-    self.assertEqual(b_c.lines, {50: 0})
-    self.assertEqual(b_c.stats, {
-        'files_executable': 1,
-        'files_instrumented': 1,
-        'lines_instrumented': 1,
-        'lines_executable': 1,
-        'lines_covered': 0,
-    })
-    self.assertEqual(b_c.in_lcov, True)
-
-    c_c = c.GetCoveredFile('_/c.c')
-    self.assertEqual(c_c.lines, {})
-    self.assertEqual(c_c.stats, {
-        'files_executable': 1,
-        'files_instrumented': 1,
-        'lines_instrumented': 0,
-        'lines_executable': 0,
-        'lines_covered': 0,
-    })
-    self.assertEqual(c_c.in_lcov, True)
-
-    # TODO: Test that files are marked as instrumented if they come from lcov,
-    # even if they don't have any instrumented lines.  (and that in_lcov is set
-    # for those files - probably should set that via some method rather than
-    # directly...)
-
-  def testGetStat(self):
-    """Test GetStat() and PrintStat()."""
-    c = self.cov
-
-    # Add some stats, so there's something to report
-    c.tree.stats_by_group = {
-        'all': {
-            'count_a': 10,
-            'count_b': 4,
-            'foo': 'bar',
-        },
-        'tests': {
-            'count_a': 2,
-            'count_b': 5,
-            'baz': 'bob',
-        },
-    }
-
-    # Test missing stats and groups
-    self.assertRaises(croc.CrocStatError, c.GetStat, 'nosuch')
-    self.assertRaises(croc.CrocStatError, c.GetStat, 'baz')
-    self.assertRaises(croc.CrocStatError, c.GetStat, 'foo', group='tests')
-    self.assertRaises(croc.CrocStatError, c.GetStat, 'foo', group='nosuch')
-
-    # Test returning defaults
-    self.assertEqual(c.GetStat('nosuch', default=13), 13)
-    self.assertEqual(c.GetStat('baz', default='aaa'), 'aaa')
-    self.assertEqual(c.GetStat('foo', group='tests', default=0), 0)
-    self.assertEqual(c.GetStat('foo', group='nosuch', default=''), '')
-
-    # Test getting stats
-    self.assertEqual(c.GetStat('count_a'), 10)
-    self.assertEqual(c.GetStat('count_a', group='tests'), 2)
-    self.assertEqual(c.GetStat('foo', default='baz'), 'bar')
-
-    # Test stat math (eval)
-    self.assertEqual(c.GetStat('count_a - count_b'), 6)
-    self.assertEqual(c.GetStat('100.0 * count_a / count_b', group='tests'),
-                     40.0)
-    # Should catch eval errors
-    self.assertRaises(croc.CrocStatError, c.GetStat, '100 / 0')
-    self.assertRaises(croc.CrocStatError, c.GetStat, 'count_a -')
-
-    # Test nested stats via S()
-    self.assertEqual(c.GetStat('count_a - S("count_a", group="tests")'), 8)
-    self.assertRaises(croc.CrocStatError, c.GetStat, 'S()')
-    self.assertRaises(croc.CrocStatError, c.GetStat, 'S("nosuch")')
-
-    # Test PrintStat()
-    # We won't see the first print, but at least verify it doesn't assert
-    c.PrintStat('count_a', format='(test to stdout: %s)')
-    # Send subsequent prints to a file
-    f = StringIO.StringIO()
-    c.PrintStat('count_b', outfile=f)
-    # Test specifying output format
-    c.PrintStat('count_a', format='Count A = %05d', outfile=f)
-    # Test specifing additional keyword args
-    c.PrintStat('count_a', group='tests', outfile=f)
-    c.PrintStat('nosuch', default=42, outfile=f)
-    self.assertEqual(f.getvalue(), ("""\
-GetStat('count_b') = 4
-Count A = 00010
-GetStat('count_a') = 2
-GetStat('nosuch') = 42
-"""))
-    f.close()
-
-  def testAddConfigEmpty(self):
-    """Test AddConfig() with empty config."""
-    c = self.cov
-    # Most minimal config is an empty dict; should do nothing
-    c.AddConfig('{} # And we ignore comments')
-
-  def testAddConfig(self):
-    """Test AddConfig()."""
-    c = self.cov
-    lcov_queue = []
-    addfiles_queue = []
-
-    c.AddConfig("""{
-        'roots' : [
-          {'root' : '/foo'},
-          {'root' : '/bar', 'altname' : 'BAR'},
-        ],
-        'rules' : [
-          {'regexp' : '^_/', 'group' : 'apple'},
-          {'regexp' : 're2', 'include' : 1, 'language' : 'elvish'},
-        ],
-        'lcov_files' : ['a.lcov', 'b.lcov'],
-        'add_files' : ['/src', 'BAR/doo'],
-        'print_stats' : [
-          {'stat' : 'count_a'},
-          {'stat' : 'count_b', 'group' : 'tests'},
-        ],
-        'extra_key' : 'is ignored',
-    }""", lcov_queue=lcov_queue, addfiles_queue=addfiles_queue)
-
-    self.assertEqual(lcov_queue, ['a.lcov', 'b.lcov'])
-    self.assertEqual(addfiles_queue, ['/src', 'BAR/doo'])
-    self.assertEqual(c.root_dirs, [['/foo', '_'], ['/bar', 'BAR']])
-    self.assertEqual(c.print_stats, [
-        {'stat': 'count_a'},
-        {'stat': 'count_b', 'group': 'tests'},
-    ])
-    # Convert compiled re's back to patterns for comparison
-    rules = [[r[0].pattern] + r[1:] for r in c.rules]
-    self.assertEqual(rules, [
-        ['^_/', {'group': 'apple'}],
-        ['re2', {'include': 1, 'language': 'elvish'}],
-    ])
-
-  def testAddFilesSimple(self):
-    """Test AddFiles() simple call."""
-    c = self.cov_minimal
-    c.add_files_walk = self.MockWalk
-    c.scan_file = self.MockScanFile
-
-    c.AddFiles('/a/b/c')
-    self.assertEqual(self.mock_walk_calls, ['/a/b/c'])
-    self.assertEqual(self.mock_scan_calls, [])
-    self.assertEqual(c.files, {})
-
-  def testAddFilesRootMap(self):
-    """Test AddFiles() with root mappings."""
-    c = self.cov_minimal
-    c.add_files_walk = self.MockWalk
-    c.scan_file = self.MockScanFile
-
-    c.AddRoot('_/subdir', 'SUBDIR')
-
-    # AddFiles() should replace the 'SUBDIR' alt_name, then match both
-    # possible roots for the '_' alt_name.
-    c.AddFiles('SUBDIR/foo')
-    self.assertEqual(self.mock_walk_calls,
-                     ['/src/subdir/foo', 'c:/source/subdir/foo'])
-    self.assertEqual(self.mock_scan_calls, [])
-    self.assertEqual(c.files, {})
-
-  def testAddFilesNonEmpty(self):
-    """Test AddFiles() where files are returned."""
-
-    c = self.cov_minimal
-    c.add_files_walk = self.MockWalk
-    c.scan_file = self.MockScanFile
-
-    # Add a rule to exclude a subdir
-    c.AddRule('^_/proj1/excluded/', include=0)
-
-    # Add a rule to exclude adding some fiels
-    c.AddRule('.*noscan.c$', add_if_missing=0)
-
-    # Set data for mock walk and scan
-    self.mock_walk_return = [
-        [
-            '/src/proj1',
-            ['excluded', 'subdir'],
-            ['a.c', 'no.f', 'yes.c', 'noexe.c', 'bob_noscan.c'],
-        ],
-        [
-            '/src/proj1/subdir',
-            [],
-            ['cherry.c'],
-        ],
-    ]
-
-    # Add a file with no executable lines; it should be scanned but not added
-    self.mock_scan_return['/src/proj1/noexe.c'] = []
-
-    c.AddFiles('/src/proj1')
-
-    self.assertEqual(self.mock_walk_calls, ['/src/proj1'])
-    self.assertEqual(self.mock_scan_calls, [
-        ['/src/proj1/a.c', 'C'],
-        ['/src/proj1/yes.c', 'C'],
-        ['/src/proj1/noexe.c', 'C'],
-        ['/src/proj1/subdir/cherry.c', 'C'],
-    ])
-
-    # Include files from the main dir and subdir
-    self.assertEqual(sorted(c.files), [
-        '_/proj1/a.c',
-        '_/proj1/subdir/cherry.c',
-        '_/proj1/yes.c'])
-
-    # Excluded dir should have been pruned from the mock walk data dirnames.
-    # In the real os.walk() call this prunes the walk.
-    self.assertEqual(self.mock_walk_return[0][1], ['subdir'])
-
-
-  def testEmptyTreeStats(self):
-    """Make sure we don't choke when absolutely nothing happened.
-
-    How we might hit this: bot compile error."""
-    c = self.cov_minimal
-    t = c.tree
-    t.stats_by_group['all'].AddDefaults()
-    self.assertEqual(t.stats_by_group, {
-        'all': { 'files_covered': 0,
-                 'files_instrumented': 0,
-                 'files_executable': 0,
-                 'lines_covered': 0,
-                 'lines_instrumented': 0,
-                 'lines_executable': 0 }})
-
-  def testUpdateTreeStats(self):
-    """Test UpdateTreeStats()."""
-
-    c = self.cov_minimal
-    c.AddRule('.*_test', group='test')
-
-    # Fill the files list
-    c.ParseLcovData([
-        'SF:/src/a.c',
-        'DA:10,1', 'DA:11,1', 'DA:20,0',
-        'end_of_record',
-        'SF:/src/a_test.c',
-        'DA:10,1', 'DA:11,1', 'DA:12,1',
-        'end_of_record',
-        'SF:/src/foo/b.c',
-        'DA:10,1', 'DA:11,1', 'DA:20,0', 'DA:21,0', 'DA:30,0',
-        'end_of_record',
-        'SF:/src/foo/b_test.c',
-        'DA:20,0', 'DA:21,0', 'DA:22,0',
-        'end_of_record',
-    ])
-    c.UpdateTreeStats()
-
-    t = c.tree
-    self.assertEqual(t.dirpath, '')
-    self.assertEqual(sorted(t.files), [])
-    self.assertEqual(sorted(t.subdirs), ['_'])
-    self.assertEqual(t.stats_by_group, {
-        'all': {
-            'files_covered': 3,
-            'files_executable': 4,
-            'lines_executable': 14,
-            'lines_covered': 7,
-            'lines_instrumented': 14,
-            'files_instrumented': 4,
-        },
-        'my': {
-            'files_covered': 2,
-            'files_executable': 2,
-            'lines_executable': 8,
-            'lines_covered': 4,
-            'lines_instrumented': 8,
-            'files_instrumented': 2,
-        },
-        'test': {
-            'files_covered': 1,
-            'files_executable': 2,
-            'lines_executable': 6,
-            'lines_covered': 3,
-            'lines_instrumented': 6,
-            'files_instrumented': 2,
-        },
-    })
-
-    t = t.subdirs['_']
-    self.assertEqual(t.dirpath, '_')
-    self.assertEqual(sorted(t.files), ['a.c', 'a_test.c'])
-    self.assertEqual(sorted(t.subdirs), ['foo'])
-    self.assertEqual(t.stats_by_group, {
-        'all': {
-            'files_covered': 3,
-            'files_executable': 4,
-            'lines_executable': 14,
-            'lines_covered': 7,
-            'lines_instrumented': 14,
-            'files_instrumented': 4,
-        },
-        'my': {
-            'files_covered': 2,
-            'files_executable': 2,
-            'lines_executable': 8,
-            'lines_covered': 4,
-            'lines_instrumented': 8,
-            'files_instrumented': 2,
-        },
-        'test': {
-            'files_covered': 1,
-            'files_executable': 2,
-            'lines_executable': 6,
-            'lines_covered': 3,
-            'lines_instrumented': 6,
-            'files_instrumented': 2,
-        },
-    })
-
-    t = t.subdirs['foo']
-    self.assertEqual(t.dirpath, '_/foo')
-    self.assertEqual(sorted(t.files), ['b.c', 'b_test.c'])
-    self.assertEqual(sorted(t.subdirs), [])
-    self.assertEqual(t.stats_by_group, {
-        'test': {
-            'files_executable': 1,
-            'files_instrumented': 1,
-            'lines_executable': 3,
-            'lines_instrumented': 3,
-            'lines_covered': 0,
-        },
-        'all': {
-            'files_covered': 1,
-            'files_executable': 2,
-            'lines_executable': 8,
-            'lines_covered': 2,
-            'lines_instrumented': 8,
-            'files_instrumented': 2,
-        },
-        'my': {
-            'files_covered': 1,
-            'files_executable': 1,
-            'lines_executable': 5,
-            'lines_covered': 2,
-            'lines_instrumented': 5,
-            'files_instrumented': 1,
-        }
-    })
-
-  # TODO: test: less important, since these are thin wrappers around other
-  # tested methods.
-  #     ParseConfig()
-  #     ParseLcovFile()
-  #     PrintTree()
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/tools/code_coverage/example.croc b/tools/code_coverage/example.croc
deleted file mode 100644
index 4e8ca2b..0000000
--- a/tools/code_coverage/example.croc
+++ /dev/null
@@ -1,197 +0,0 @@
-# -*- python -*-

-

-# 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.

-

-# Example configuration file for Croc

-

-# Basic formatting rules:

-#   * It looks like JSON.

-#   * It's really python.

-#   * Dictionaries are wrapped in {}.  Order does not matter.  Entries are of

-#     the form:

-#         'key':value,

-#     Note the trailing comma, which will help save you from python's built-in

-#     string concatenation.

-#   * Lists are wrapped in [].  Order does matter.  Entries should be followed

-#     with a trailing comma, which will help save you from python's built-in

-#     string concatenation.

-#   * Comments start with # and extend to end of line.

-#   * Strings are wrapped in ''.  Backslashes must be escaped ('foo\\bar', not

-#     'foo\bar') - this is particularly important in rule regular expressions.

-

-

-# What follows is the main configuration dictionary.

-{

-  # List of root directories, applied in order.

-  #

-  # Typically, coverage data files contain absolute paths to the sources.

-  # What you care about is usually a relative path from the top of your source

-  # tree (referred to here as a 'source root') to the sources.

-  #

-  # Roots may also be specified on the command line via the --root option.

-  # Roots specified by --root are applied before those specified in config

-  # files.

-  'roots' : [

-    # Each entry is a dict.

-    #     * It must contain a 'root' entry, which is the start of a path.

-    #         * Root entries may be absolute paths

-    #         * Root entries starting with './' or '../' are relative paths, and

-    #           are taken relative to the current directory where you run croc.

-    #         * Root entries may start with previously defined altnames.

-    #         * Use '/' as a path separator, even on Windows.

-    #     * It may contain a 'altname' entry.  If the root matches the start of

-    #        a filename, that start is replaced with the 'altname', or with '_'

-    #        if no default is specified.

-    #     * Multiple root entries may share the same altname.  This is commonly

-    #       used when combining LCOV files from different platforms into one

-    #       coverage report, when each platform checks out source code into a

-    #       different source tree.

-    {'root' : 'c:/P4/EarthHammer'},

-    {'root' : 'd:/pulse/recipes/330137642/base'},

-    {'root' : '/Volumes/BuildData/PulseData/data/recipes/330137640/base'},

-    {'root' : '/usr/local/google/builder/.pulse-agent/data/recipes/330137641/base'},

-

-    # Sub-paths we specifically care about and want to call out.  Note that

-    # these are relative to the default '_' altname.

-    {

-      'root' : '_/googleclient/third_party/software_construction_toolkit/files',

-      'altname' : 'SCT',

-    },

-    {

-      'root' : '_/googleclient/tools/hammer',

-      'altname' : 'HAMMER',

-    },

-  ],

-

-  # List of rules, applied in order.

-  'rules' : [

-    # Each rule is a dict.

-    #   * It must contaihn a 'regexp' entry.  Filenames which match this

-    #     regular expression (after applying mappings from 'roots') are

-    #     affected by the rule.

-    #

-    #   * Other entries in the dict are attributes to apply to matching files.

-    #

-    # Allowed attributes:

-    #

-    #   'include' : If 1, the file will be included in coverage reports.  If 0,

-    #               it won't be included in coverage reports.

-    #

-    #   'group' : Name of the group the file belongs to.  The most common

-    #             group names are 'source' and 'test'.  Files must belong to

-    #             a group to be included in coverage reports.

-    #

-    #   'language' : Programming language for the file.  The most common

-    #                languages are 'C', 'C++', 'python', 'ObjC', 'ObjC++'.

-    #                Files must have a language to be included in coverage

-    #                reports.

-    #

-    #   'add_if_missing' : If 1, and the file was not referenced by any LCOV

-    #                      files, it will be be scanned for executable lines

-    #                      and added to the coverage report.  If 0, if the

-    #                      file is not referenced by any LCOV files, it will

-    #                      simply be ignored and not present in coverage

-    #                      reports.

-

-    # Files/paths to include

-    {

-      'regexp' : '^(SCT|HAMMER)/',

-      'include' : 1,

-      'add_if_missing': 1,

-    },

-    {

-      'regexp' : '.*/(\\.svn|\\.hg)/',

-      'include' : 0,

-    },

-

-    # Groups

-    {

-      'regexp' : '',

-      'group' : 'source',

-    },

-    {

-      'regexp' : '.*_(test|test_mac|unittest)\\.',

-      'group' : 'test',

-    },

-

-    # Languages

-    {

-      'regexp' : '.*\\.py$',

-      'language' : 'python',

-    },

-  ],

-

-  # List of paths to add source from.

-  #

-  # Each entry is a path.  It may be a local path, or one relative to a root

-  # altname (see 'roots' above).

-  #

-  # If more than one root's altname matches the start of this path, all matches

-  # will be attempted; matches where the candidate directory doesn't exist will

-  # be ignored.  For example, if you're combining data from multiple platforms'

-  # LCOV files, you probably defined at least one root per LCOV, but only have

-  # one copy of the source on your local platform.  That's fine; Croc will use

-  # the source it can find and not worry about the source it can't.

-  #

-  # Source files must be added via 'add_files' to generate line-by-line HTML

-  # output (via the --html option) and/or to scan for missing executable lines

-  # (if 'add_if_missing' is 1).

-  'add_files' : [

-    'SCT',

-    'HAMMER',

-  ],

-

-  # Statistics to print.

-  #

-  'print_stats' : [

-    # Each entry is a dict.

-    #

-    # It must have a 'stat' entry, which is the statistic to print.  This may

-    # be one of the following stats:

-    #

-    #   * files_executable

-    #   * files_instrumented

-    #   * files_covered

-    #   * lines_executable

-    #   * lines_instrumented

-    #   * lines_covered

-    #

-    # or an expression using those stats.

-    #

-    # It may have a 'format' entry, which is a python formatting string (very

-    # printf-like) for the statistic.

-    #

-    # It may have a 'group' entry.  If this is specified, only files from the

-    # matching group will be included in the statistic.  If not specified, the

-    # group defaults to 'all', which means all groups.

-    {

-      'stat' : 'files_executable',

-      'format' : '*RESULT FilesKnown: files_executable= %d files',

-    },

-    {

-      'stat' : 'files_instrumented',

-      'format' : '*RESULT FilesInstrumented: files_instrumented= %d files',

-    },

-    {

-      'stat' : '100.0 * files_instrumented / files_executable',

-      'format' : '*RESULT FilesInstrumentedPercent: files_instrumented_percent= %g',

-    },

-    {

-      'stat' : 'lines_instrumented',

-      'format' : '*RESULT LinesInstrumented: lines_instrumented= %d lines',

-    },

-    {

-      'stat' : 'lines_covered',

-      'format' : '*RESULT LinesCoveredSource: lines_covered_source= %d lines',

-      'group' : 'source',

-    },

-    {

-      'stat' : 'lines_covered',

-      'format' : '*RESULT LinesCoveredTest: lines_covered_test= %d lines',

-      'group' : 'test',

-    },

-  ],

-

-}

diff --git a/tools/code_coverage/third_party/README.chromium b/tools/code_coverage/third_party/README.chromium
deleted file mode 100644
index a492552..0000000
--- a/tools/code_coverage/third_party/README.chromium
+++ /dev/null
@@ -1,11 +0,0 @@
-Name: SortTable
-Short Name: sorttable.js
-URL: http://www.kryogenix.org/code/browser/sorttable/
-Version: 2
-Date: 7th April 2007
-License: Licenced as X11: http://www.kryogenix.org/code/browser/licence.html
-
-Description:
-Add <script src="sorttable.js"></script> to your HTML
-Add class="sortable" to any table you'd like to make sortable
-Click on the headers to sort
diff --git a/tools/code_coverage/third_party/sorttable.js b/tools/code_coverage/third_party/sorttable.js
deleted file mode 100644
index 16ef551..0000000
--- a/tools/code_coverage/third_party/sorttable.js
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
-  SortTable
-  version 2
-  7th April 2007
-  Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/
-  
-  Instructions:
-  Download this file
-  Add <script src="sorttable.js"></script> to your HTML
-  Add class="sortable" to any table you'd like to make sortable
-  Click on the headers to sort
-  
-  Thanks to many, many people for contributions and suggestions.
-  Licenced as X11: http://www.kryogenix.org/code/browser/licence.html
-  This basically means: do what you want with it.
-*/
-
- 
-var stIsIE = /*@cc_on!@*/false;
-
-sorttable = {
-  init: function() {
-    // quit if this function has already been called
-    if (arguments.callee.done) return;
-    // flag this function so we don't do the same thing twice
-    arguments.callee.done = true;
-    // kill the timer
-    if (_timer) clearInterval(_timer);
-    
-    if (!document.createElement || !document.getElementsByTagName) return;
-    
-    sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
-    
-    forEach(document.getElementsByTagName('table'), function(table) {
-      if (table.className.search(/\bsortable\b/) != -1) {
-        sorttable.makeSortable(table);
-      }
-    });
-    
-  },
-  
-  makeSortable: function(table) {
-    if (table.getElementsByTagName('thead').length == 0) {
-      // table doesn't have a tHead. Since it should have, create one and
-      // put the first table row in it.
-      the = document.createElement('thead');
-      the.appendChild(table.rows[0]);
-      table.insertBefore(the,table.firstChild);
-    }
-    // Safari doesn't support table.tHead, sigh
-    if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0];
-    
-    if (table.tHead.rows.length != 1) return; // can't cope with two header rows
-    
-    // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as
-    // "total" rows, for example). This is B&R, since what you're supposed
-    // to do is put them in a tfoot. So, if there are sortbottom rows,
-    // for backwards compatibility, move them to tfoot (creating it if needed).
-    sortbottomrows = [];
-    for (var i=0; i<table.rows.length; i++) {
-      if (table.rows[i].className.search(/\bsortbottom\b/) != -1) {
-        sortbottomrows[sortbottomrows.length] = table.rows[i];
-      }
-    }
-    if (sortbottomrows) {
-      if (table.tFoot == null) {
-        // table doesn't have a tfoot. Create one.
-        tfo = document.createElement('tfoot');
-        table.appendChild(tfo);
-      }
-      for (var i=0; i<sortbottomrows.length; i++) {
-        tfo.appendChild(sortbottomrows[i]);
-      }
-      delete sortbottomrows;
-    }
-    
-    // work through each column and calculate its type
-    headrow = table.tHead.rows[0].cells;
-    for (var i=0; i<headrow.length; i++) {
-      // manually override the type with a sorttable_type attribute
-      if (!headrow[i].className.match(/\bsorttable_nosort\b/)) { // skip this col
-        mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/);
-        if (mtch) { override = mtch[1]; }
-	      if (mtch && typeof sorttable["sort_"+override] == 'function') {
-	        headrow[i].sorttable_sortfunction = sorttable["sort_"+override];
-	      } else {
-	        headrow[i].sorttable_sortfunction = sorttable.guessType(table,i);
-	      }
-	      // make it clickable to sort
-	      headrow[i].sorttable_columnindex = i;
-	      headrow[i].sorttable_tbody = table.tBodies[0];
-	      dean_addEvent(headrow[i],"click", function(e) {
-
-          if (this.className.search(/\bsorttable_sorted\b/) != -1) {
-            // if we're already sorted by this column, just 
-            // reverse the table, which is quicker
-            sorttable.reverse(this.sorttable_tbody);
-            this.className = this.className.replace('sorttable_sorted',
-                                                    'sorttable_sorted_reverse');
-            this.removeChild(document.getElementById('sorttable_sortfwdind'));
-            sortrevind = document.createElement('span');
-            sortrevind.id = "sorttable_sortrevind";
-            sortrevind.innerHTML = stIsIE ? '&nbsp<font face="webdings">5</font>' : '&nbsp;&#x25B4;';
-            this.appendChild(sortrevind);
-            return;
-          }
-          if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
-            // if we're already sorted by this column in reverse, just 
-            // re-reverse the table, which is quicker
-            sorttable.reverse(this.sorttable_tbody);
-            this.className = this.className.replace('sorttable_sorted_reverse',
-                                                    'sorttable_sorted');
-            this.removeChild(document.getElementById('sorttable_sortrevind'));
-            sortfwdind = document.createElement('span');
-            sortfwdind.id = "sorttable_sortfwdind";
-            sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;';
-            this.appendChild(sortfwdind);
-            return;
-          }
-          
-          // remove sorttable_sorted classes
-          theadrow = this.parentNode;
-          forEach(theadrow.childNodes, function(cell) {
-            if (cell.nodeType == 1) { // an element
-              cell.className = cell.className.replace('sorttable_sorted_reverse','');
-              cell.className = cell.className.replace('sorttable_sorted','');
-            }
-          });
-          sortfwdind = document.getElementById('sorttable_sortfwdind');
-          if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); }
-          sortrevind = document.getElementById('sorttable_sortrevind');
-          if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); }
-          
-          this.className += ' sorttable_sorted';
-          sortfwdind = document.createElement('span');
-          sortfwdind.id = "sorttable_sortfwdind";
-          sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;';
-          this.appendChild(sortfwdind);
-
-	        // build an array to sort. This is a Schwartzian transform thing,
-	        // i.e., we "decorate" each row with the actual sort key,
-	        // sort based on the sort keys, and then put the rows back in order
-	        // which is a lot faster because you only do getInnerText once per row
-	        row_array = [];
-	        col = this.sorttable_columnindex;
-	        rows = this.sorttable_tbody.rows;
-	        for (var j=0; j<rows.length; j++) {
-	          row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]];
-	        }
-	        /* If you want a stable sort, uncomment the following line */
-	        //sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
-	        /* and comment out this one */
-	        row_array.sort(this.sorttable_sortfunction);
-	        
-	        tb = this.sorttable_tbody;
-	        for (var j=0; j<row_array.length; j++) {
-	          tb.appendChild(row_array[j][1]);
-	        }
-	        
-	        delete row_array;
-	      });
-	    }
-    }
-  },
-  
-  guessType: function(table, column) {
-    // guess the type of a column based on its first non-blank row
-    sortfn = sorttable.sort_alpha;
-    for (var i=0; i<table.tBodies[0].rows.length; i++) {
-      text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]);
-      if (text != '') {
-        if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) {
-          return sorttable.sort_numeric;
-        }
-        // check for a date: dd/mm/yyyy or dd/mm/yy 
-        // can have / or . or - as separator
-        // can be mm/dd as well
-        possdate = text.match(sorttable.DATE_RE)
-        if (possdate) {
-          // looks like a date
-          first = parseInt(possdate[1]);
-          second = parseInt(possdate[2]);
-          if (first > 12) {
-            // definitely dd/mm
-            return sorttable.sort_ddmm;
-          } else if (second > 12) {
-            return sorttable.sort_mmdd;
-          } else {
-            // looks like a date, but we can't tell which, so assume
-            // that it's dd/mm (English imperialism!) and keep looking
-            sortfn = sorttable.sort_ddmm;
-          }
-        }
-      }
-    }
-    return sortfn;
-  },
-  
-  getInnerText: function(node) {
-    // gets the text we want to use for sorting for a cell.
-    // strips leading and trailing whitespace.
-    // this is *not* a generic getInnerText function; it's special to sorttable.
-    // for example, you can override the cell text with a customkey attribute.
-    // it also gets .value for <input> fields.
-    
-    if (!node) return "";
-
-    hasInputs = (typeof node.getElementsByTagName == 'function') &&
-                 node.getElementsByTagName('input').length;
-    
-    if (node.getAttribute("sorttable_customkey") != null) {
-      return node.getAttribute("sorttable_customkey");
-    }
-    else if (typeof node.textContent != 'undefined' && !hasInputs) {
-      return node.textContent.replace(/^\s+|\s+$/g, '');
-    }
-    else if (typeof node.innerText != 'undefined' && !hasInputs) {
-      return node.innerText.replace(/^\s+|\s+$/g, '');
-    }
-    else if (typeof node.text != 'undefined' && !hasInputs) {
-      return node.text.replace(/^\s+|\s+$/g, '');
-    }
-    else {
-      switch (node.nodeType) {
-        case 3:
-          if (node.nodeName.toLowerCase() == 'input') {
-            return node.value.replace(/^\s+|\s+$/g, '');
-          }
-        case 4:
-          return node.nodeValue.replace(/^\s+|\s+$/g, '');
-          break;
-        case 1:
-        case 11:
-          var innerText = '';
-          for (var i = 0; i < node.childNodes.length; i++) {
-            innerText += sorttable.getInnerText(node.childNodes[i]);
-          }
-          return innerText.replace(/^\s+|\s+$/g, '');
-          break;
-        default:
-          return '';
-      }
-    }
-  },
-  
-  reverse: function(tbody) {
-    // reverse the rows in a tbody
-    newrows = [];
-    for (var i=0; i<tbody.rows.length; i++) {
-      newrows[newrows.length] = tbody.rows[i];
-    }
-    for (var i=newrows.length-1; i>=0; i--) {
-       tbody.appendChild(newrows[i]);
-    }
-    delete newrows;
-  },
-  
-  /* sort functions
-     each sort function takes two parameters, a and b
-     you are comparing a[0] and b[0] */
-  sort_numeric: function(a,b) {
-    aa = parseFloat(a[0].replace(/[^0-9.-]/g,''));
-    if (isNaN(aa)) aa = 0;
-    bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); 
-    if (isNaN(bb)) bb = 0;
-    return aa-bb;
-  },
-  sort_alpha: function(a,b) {
-    if (a[0]==b[0]) return 0;
-    if (a[0]<b[0]) return -1;
-    return 1;
-  },
-  sort_ddmm: function(a,b) {
-    mtch = a[0].match(sorttable.DATE_RE);
-    y = mtch[3]; m = mtch[2]; d = mtch[1];
-    if (m.length == 1) m = '0'+m;
-    if (d.length == 1) d = '0'+d;
-    dt1 = y+m+d;
-    mtch = b[0].match(sorttable.DATE_RE);
-    y = mtch[3]; m = mtch[2]; d = mtch[1];
-    if (m.length == 1) m = '0'+m;
-    if (d.length == 1) d = '0'+d;
-    dt2 = y+m+d;
-    if (dt1==dt2) return 0;
-    if (dt1<dt2) return -1;
-    return 1;
-  },
-  sort_mmdd: function(a,b) {
-    mtch = a[0].match(sorttable.DATE_RE);
-    y = mtch[3]; d = mtch[2]; m = mtch[1];
-    if (m.length == 1) m = '0'+m;
-    if (d.length == 1) d = '0'+d;
-    dt1 = y+m+d;
-    mtch = b[0].match(sorttable.DATE_RE);
-    y = mtch[3]; d = mtch[2]; m = mtch[1];
-    if (m.length == 1) m = '0'+m;
-    if (d.length == 1) d = '0'+d;
-    dt2 = y+m+d;
-    if (dt1==dt2) return 0;
-    if (dt1<dt2) return -1;
-    return 1;
-  },
-  
-  shaker_sort: function(list, comp_func) {
-    // A stable sort function to allow multi-level sorting of data
-    // see: http://en.wikipedia.org/wiki/Cocktail_sort
-    // thanks to Joseph Nahmias
-    var b = 0;
-    var t = list.length - 1;
-    var swap = true;
-
-    while(swap) {
-        swap = false;
-        for(var i = b; i < t; ++i) {
-            if ( comp_func(list[i], list[i+1]) > 0 ) {
-                var q = list[i]; list[i] = list[i+1]; list[i+1] = q;
-                swap = true;
-            }
-        } // for
-        t--;
-
-        if (!swap) break;
-
-        for(var i = t; i > b; --i) {
-            if ( comp_func(list[i], list[i-1]) < 0 ) {
-                var q = list[i]; list[i] = list[i-1]; list[i-1] = q;
-                swap = true;
-            }
-        } // for
-        b++;
-
-    } // while(swap)
-  }  
-}
-
-/* ******************************************************************
-   Supporting functions: bundled here to avoid depending on a library
-   ****************************************************************** */
-
-// Dean Edwards/Matthias Miller/John Resig
-
-/* for Mozilla/Opera9 */
-if (document.addEventListener) {
-    document.addEventListener("DOMContentLoaded", sorttable.init, false);
-}
-
-/* for Internet Explorer */
-/*@cc_on @*/
-/*@if (@_win32)
-    document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
-    var script = document.getElementById("__ie_onload");
-    script.onreadystatechange = function() {
-        if (this.readyState == "complete") {
-            sorttable.init(); // call the onload handler
-        }
-    };
-/*@end @*/
-
-/* for Safari */
-if (/WebKit/i.test(navigator.userAgent)) { // sniff
-    var _timer = setInterval(function() {
-        if (/loaded|complete/.test(document.readyState)) {
-            sorttable.init(); // call the onload handler
-        }
-    }, 10);
-}
-
-/* for other browsers */
-window.onload = sorttable.init;
-
-// written by Dean Edwards, 2005
-// with input from Tino Zijdel, Matthias Miller, Diego Perini
-
-// http://dean.edwards.name/weblog/2005/10/add-event/
-
-function dean_addEvent(element, type, handler) {
-	if (element.addEventListener) {
-		element.addEventListener(type, handler, false);
-	} else {
-		// assign each event handler a unique ID
-		if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++;
-		// create a hash table of event types for the element
-		if (!element.events) element.events = {};
-		// create a hash table of event handlers for each element/event pair
-		var handlers = element.events[type];
-		if (!handlers) {
-			handlers = element.events[type] = {};
-			// store the existing event handler (if there is one)
-			if (element["on" + type]) {
-				handlers[0] = element["on" + type];
-			}
-		}
-		// store the event handler in the hash table
-		handlers[handler.$$guid] = handler;
-		// assign a global event handler to do all the work
-		element["on" + type] = handleEvent;
-	}
-};
-// a counter used to create unique IDs
-dean_addEvent.guid = 1;
-
-function removeEvent(element, type, handler) {
-	if (element.removeEventListener) {
-		element.removeEventListener(type, handler, false);
-	} else {
-		// delete the event handler from the hash table
-		if (element.events && element.events[type]) {
-			delete element.events[type][handler.$$guid];
-		}
-	}
-};
-
-function handleEvent(event) {
-	var returnValue = true;
-	// grab the event object (IE uses a global event object)
-	event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
-	// get a reference to the hash table of event handlers
-	var handlers = this.events[event.type];
-	// execute each event handler
-	for (var i in handlers) {
-		this.$$handleEvent = handlers[i];
-		if (this.$$handleEvent(event) === false) {
-			returnValue = false;
-		}
-	}
-	return returnValue;
-};
-
-function fixEvent(event) {
-	// add W3C standard event methods
-	event.preventDefault = fixEvent.preventDefault;
-	event.stopPropagation = fixEvent.stopPropagation;
-	return event;
-};
-fixEvent.preventDefault = function() {
-	this.returnValue = false;
-};
-fixEvent.stopPropagation = function() {
-  this.cancelBubble = true;
-}
-
-// Dean's forEach: http://dean.edwards.name/base/forEach.js
-/*
-	forEach, version 1.0
-	Copyright 2006, Dean Edwards
-	License: http://www.opensource.org/licenses/mit-license.php
-*/
-
-// array-like enumeration
-if (!Array.forEach) { // mozilla already supports this
-	Array.forEach = function(array, block, context) {
-		for (var i = 0; i < array.length; i++) {
-			block.call(context, array[i], i, array);
-		}
-	};
-}
-
-// generic enumeration
-Function.prototype.forEach = function(object, block, context) {
-	for (var key in object) {
-		if (typeof this.prototype[key] == "undefined") {
-			block.call(context, object[key], key, object);
-		}
-	}
-};
-
-// character enumeration
-String.forEach = function(string, block, context) {
-	Array.forEach(string.split(""), function(chr, index) {
-		block.call(context, chr, index, string);
-	});
-};
-
-// globally resolve forEach enumeration
-var forEach = function(object, block, context) {
-	if (object) {
-		var resolve = Object; // default
-		if (object instanceof Function) {
-			// functions have a "length" property
-			resolve = Function;
-		} else if (object.forEach instanceof Function) {
-			// the object implements a custom forEach method so use that
-			object.forEach(block, context);
-			return;
-		} else if (typeof object == "string") {
-			// the object is a string
-			resolve = String;
-		} else if (typeof object.length == "number") {
-			// the object is array-like
-			resolve = Array;
-		}
-		resolve.forEach(object, block, context);
-	}
-};
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 7cfc7f2..50628be 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -102648,6 +102648,9 @@
 </histogram_suffixes>
 
 <histogram_suffixes name="LowMemoryMargin" separator="_">
+  <obsolete>
+    Deprecated 12/2017. The low memory margin is a per-platform constant.
+  </obsolete>
   <suffix name="default" label="Low memory margin set to the system default"/>
   <suffix name="off" label="Low memory notification disabled"/>
   <suffix name="0mb" label="Low memory margin set to 0MB"/>
diff --git a/ui/views/layout/grid_layout.cc b/ui/views/layout/grid_layout.cc
index 8fba648..3060f64 100644
--- a/ui/views/layout/grid_layout.cc
+++ b/ui/views/layout/grid_layout.cc
@@ -364,6 +364,10 @@
   const bool pref_width_fixed;
   const bool pref_height_fixed;
 
+  // The preferred size, only set during the preferred size pass
+  // (SizeCalculationType::PREFERRED).
+  gfx::Size pref_size;
+
   // The width/height. This is one of possible three values:
   // . an explicitly set value (if pref_X_fixed is true). If an explicitly set
   //   value was provided, then this value never changes.
@@ -630,6 +634,7 @@
           size.set_height(view_state->height);
       } else {
         size = view_state->view->GetPreferredSize();
+        view_state->pref_size = size;
       }
       if (!view_state->pref_width_fixed)
         view_state->width = size.width();
@@ -986,20 +991,22 @@
   //   view and update the rows ascent/descent.
   // . Reset the remaining_height of each view state.
   // . If the width the view will be given is different than it's pref, ask
-  //   for the height given a particularly width.
+  //   for the height given the actual width.
   for (const auto& view_state : view_states_) {
     view_state->remaining_height = view_state->height;
 
     if (view_state->v_align == BASELINE)
       view_state->baseline = view_state->view->GetBaseline();
 
-    if (view_state->h_align == FILL) {
-      // The view is resizable. As the pref height may vary with the width,
-      // ask for the pref again.
-      int actual_width =
-          view_state->column_set->GetColumnWidth(view_state->start_col,
-                                                 view_state->col_span);
-      if (actual_width != view_state->width && !view_state->pref_height_fixed) {
+    if (!view_state->pref_height_fixed) {
+      // If the view is given a different width than it's preferred width
+      // requery for the preferred height. This is necessary as the preferred
+      // height may depend upon the width.
+      int actual_width = view_state->column_set->GetColumnWidth(
+          view_state->start_col, view_state->col_span);
+      int x = 0;  // Not used in this stage.
+      CalculateSize(view_state->width, view_state->h_align, &x, &actual_width);
+      if (actual_width != view_state->width) {
         // The width this view will get differs from its preferred. Some Views
         // pref height varies with its width; ask for the preferred again.
         view_state->height = view_state->view->GetHeightForWidth(actual_width);
diff --git a/ui/views/layout/grid_layout_unittest.cc b/ui/views/layout/grid_layout_unittest.cc
index 31bc7c6..f993c6f 100644
--- a/ui/views/layout/grid_layout_unittest.cc
+++ b/ui/views/layout/grid_layout_unittest.cc
@@ -1023,4 +1023,35 @@
   EXPECT_EQ(gfx::Rect(10, 0, 50, 10), view2->bounds());
 }
 
+class SettablePreferredHeightView : public View {
+ public:
+  explicit SettablePreferredHeightView(int height) : pref_height_(height) {}
+  ~SettablePreferredHeightView() override = default;
+
+  // View:
+  int GetHeightForWidth(int width) const override { return pref_height_; }
+
+ private:
+  const int pref_height_;
+
+  DISALLOW_COPY_AND_ASSIGN(SettablePreferredHeightView);
+};
+
+TEST_F(GridLayoutTest, HeightForWidthCalledWhenNotGivenPreferredWidth) {
+  ColumnSet* set = layout()->AddColumnSet(0);
+  set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, GridLayout::USE_PREF,
+                 0, 0);
+  layout()->StartRow(0, 0);
+  const int pref_height = 100;
+  // |view| is owned by parent.
+  SettablePreferredHeightView* view =
+      new SettablePreferredHeightView(pref_height);
+  const gfx::Size pref(10, 20);
+  view->SetPreferredSize(pref);
+  layout()->AddView(view);
+
+  EXPECT_EQ(pref, GetPreferredSize());
+  EXPECT_EQ(pref_height, host().GetHeightForWidth(5));
+}
+
 }  // namespace views